many pins, how to distinguish each pin? - iphone

Please help me, I am stuck with this MapView:
I have a MapView and a small label under that MapView. On the MapView, I have many pins (MKPinAnnotationView), I know how to set the title and subtitle of each pin by using array, but I do not know how to distinguish each pin. I mean when user taps a pin, the label will show the title of the tapped pin.
Here is some of my code:
This is where I define the pin:
#implementation PlacePin
#synthesize coordinate,title,subtitle;
#synthesize nTag;
- (id)initWithLocation:(CLLocationCoordinate2D)coord{
self = [super init];
if (self) {
coordinate = coord;
}
return self;
}
-(void)dealloc{
[title release];
[subtitle release];
[super dealloc];
}
#end
This is where I proccess the result from server:
- (void) resultCheck {
NSString *strUrl = [NSString stringWithFormat:#"ServerAddress.com"];
NSLog(#"MapView - resultCheck: url: %# ", strUrl);
NSURL *url = [ NSURL URLWithString:strUrl];
//get the result from server
NSString *result = [NSString stringWithContentsOfURL:url];
NSLog(#"MapView - resultCheck: result: %#", result);
NSDictionary *dictionary = [result JSONValue];
NSLog(#"MapView - resultCheck: dictionary: %#", dictionary);
//process the JSON, get two parameters: xPos, yPos
NSDictionary *value1 = [dictionary valueForKey:#"result"];
NSDictionary *value2 = [value1 valueForKey:#"post"];
NSArray *arrXPos = [value2 valueForKey:#"xPos"]; //array of xPos
NSArray *arrYPos = [value2 valueForKey:#"yPos"]; //array of yPos
self.arrName = [value2 valueForKey:#"name"]; //array of name
self.arrPlaceInfor = [value2 valueForKey:#"place_info"];
NSLog(#"MapView - resultCheck: value1: %#",value1);
NSLog(#"MapView - resultCheck: value2: %#",value2);
NSLog(#"MapView - resultCheck: value3: %#",arrXPos);
NSLog(#"MapView - resultCheck: value4: %#",arrYPos);
//get the xPos and yPos
for (int i = 0 ; i < [value2 count]; i++) {
//display the place depended on the xPos and yPos
CLLocationCoordinate2D location;
location.latitude = [[ NSString stringWithFormat:#"%#",[arrXPos objectAtIndex:i]] doubleValue];
location.longitude = [[ NSString stringWithFormat:#"%#",[arrYPos objectAtIndex:i]] doubleValue];
PlacePin *mapPoint = [[PlacePin alloc] initWithLocation:location];
//set the title and subtitle of the pin depending on the result from server
mapPoint.title = [ NSString stringWithFormat:#"%#",[self.arrName objectAtIndex:i]];
mapPoint.subtitle = [ NSString stringWithFormat:#"%#",[self.arrPlaceInfor objectAtIndex:i]];
[mapView addAnnotation:mapPoint];
[mapPoint release];
mapPoint = nil;
}
}
This is where I proccess the pin and set the label - where I am getting stuck :(
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view NS_AVAILABLE(NA, 4_0){
self.labelShortIntro.text = #"1111111111111";
}
//customize an annotation
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation{
MKPinAnnotationView *annView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"currentloc"];
annView.pinColor = MKPinAnnotationColorPurple;
annView.animatesDrop = TRUE;
annView.canShowCallout = YES;
annView.calloutOffset = CGPointMake(-5, 5);
return annView;
}

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{
PlacePin *selectedPin = view.annotation;
NSLog(#"Title = %# Subtitle = %#",selectedPin.title,selectedPin.subtitle);
self.labelShortIntro.text = [NSString stringWithFormat:#"Title = %# Subtitle = %#",selectedPin.title,selectedPin.subtitle];
}

in didSelectAnnotationView delegate:
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
NSArray *selectedAnnotations = mapView.selectedAnnotations;
for(PlacePin *ann in selectedAnnotations)
{
NSLog(#"%#",ann.title);
self.labelShortIntro.text=ann.title;
}
}
I hope this code will help you.

Related

iPhone: How to draw line between two points on MapKit?

I have Latitude and Longitude of two points and Want to Draw line between these two points with Pin on MapKit.
I have googled but Could not find some suitable solution because the one I found was drawing overlay with array of Data points but I do not have any array of points between these two points.
Just two points and want to draw line between these two points.
Please help.
First make your view controller implement the MKMapViewDelegate protocol and declare the properties you will need:
#property (nonatomic, retain) MKMapView *mapView; //this is your map view
#property (nonatomic, retain) MKPolyline *routeLine; //your line
#property (nonatomic, retain) MKPolylineView *routeLineView; //overlay view
then in viewDidLoad (for example, or wherever you initialize)
//initialize your map view and add it to your view hierarchy - **set its delegate to self***
CLLocationCoordinate2D coordinateArray[2];
coordinateArray[0] = CLLocationCoordinate2DMake(lat1, lon1);
coordinateArray[1] = CLLocationCoordinate2DMake(lat2, lon2);
self.routeLine = [MKPolyline polylineWithCoordinates:coordinateArray count:2];
[self.mapView setVisibleMapRect:[self.routeLine boundingMapRect]]; //If you want the route to be visible
[self.mapView addOverlay:self.routeLine];
then implement the MKMapViewDelegate's method -(MKOverlayView *)mapView:viewForOverlay:
-(MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay
{
if(overlay == self.routeLine)
{
if(nil == self.routeLineView)
{
self.routeLineView = [[[MKPolylineView alloc] initWithPolyline:self.routeLine] autorelease];
self.routeLineView.fillColor = [UIColor redColor];
self.routeLineView.strokeColor = [UIColor redColor];
self.routeLineView.lineWidth = 5;
}
return self.routeLineView;
}
return nil;
}
You can adjust the code to fit your need, but it's pretty much straight forward for 2 or more points.
Please See this tutorial to draw polyline or route in mkmapview
1>Draw route using mapkit
2>From versions above ios4.0 You can use MKOverlayPathView See Apple Docs
Sample code :-
create PolyLine:-
-(void) loadRoute
{
NSString* filePath = [[NSBundle mainBundle] pathForResource:#”route” ofType:#”csv”];
NSString* fileContents = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
NSArray* pointStrings = [fileContents componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
MKMapPoint northEastPoint;
MKMapPoint southWestPoint;
MKMapPoint* pointArr = malloc(sizeof(CLLocationCoordinate2D) * pointStrings.count);
for(int idx = 0; idx < pointStrings.count; idx++)
{
NSString* currentPointString = [pointStrings objectAtIndex:idx];
NSArray* latLonArr = [currentPointString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#","]];
CLLocationDegrees latitude = [[latLonArr objectAtIndex:0] doubleValue];
CLLocationDegrees longitude = [[latLonArr objectAtIndex:1] doubleValue];
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude);
MKMapPoint point = MKMapPointForCoordinate(coordinate);
if (idx == 0) {
northEastPoint = point;
southWestPoint = point;
}
else
{
if (point.x > northEastPoint.x)
northEastPoint.x = point.x;
if(point.y > northEastPoint.y)
northEastPoint.y = point.y;
if (point.x < southWestPoint.x)
southWestPoint.x = point.x;
if (point.y < southWestPoint.y)
southWestPoint.y = point.y;
}
pointArr[idx] = point;
}
self.routeLine = [MKPolyline polylineWithPoints:pointArr count:pointStrings.count];
_routeRect = MKMapRectMake(southWestPoint.x, southWestPoint.y, northEastPoint.x - southWestPoint.x, northEastPoint.y - southWestPoint.y);
free(pointArr);
}
Display PoluLine :-
[self.mapView addOverlay:self.routeLine];
Adding the overlay alone will not render anything on the map. Your MKMapViewDelegate implementation must return an overlay for this route you’ve just added as simply adding won't help .
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id )overlay
{
MKOverlayView* overlayView = nil;
if(overlay == self.routeLine)
{
//if we have not yet created an overlay view for this overlay, create it now.
if(nil == self.routeLineView)
{
self.routeLineView = [[[MKPolylineView alloc] initWithPolyline:self.routeLine] autorelease];
self.routeLineView.fillColor = [UIColor redColor];
self.routeLineView.strokeColor = [UIColor redColor];
self.routeLineView.lineWidth = 3;
}
overlayView = self.routeLineView;
}
return overlayView;
}
#import <MapKit/MapKit.h>
- (void)viewDidLoad
{
[mapview setDelegate:self];
mapview.showsUserLocation = YES;
}
- (CLLocationCoordinate2D)coordinateWithLocation:(NSDictionary*)location
{
double latitude = [[location objectForKey:#"lat"] doubleValue];
double longitude = [[location objectForKey:#"lng"] doubleValue];
return CLLocationCoordinate2DMake(latitude, longitude);
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateSpan span = MKCoordinateSpanMake(0.005, 0.005);
MKCoordinateRegion region = MKCoordinateRegionMake(userLocation.location.coordinate, span);
[mapview setRegion:region];
[mapview setCenterCoordinate:userLocation.coordinate animated:YES];
NSString *baseUrl = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/directions/json?origin=%f,%f&destination=%#&sensor=true", mapview.userLocation.location.coordinate.latitude, mapview.userLocation.location.coordinate.longitude, #"24.1620661,72.394131"];
//http://maps.googleapis.com/maps/api/directions/json?origin=23.030000,72.580000&destination=23.400000,72.750000&sensor=true
NSURL *url = [NSURL URLWithString:[baseUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSLog(#"%#",url);
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSError *error = nil;
NSDictionary *result = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSArray *routes = [result objectForKey:#"routes"];
NSLog(#"%#",routes);
NSDictionary *firstRoute = [routes objectAtIndex:0];
NSDictionary *leg = [[firstRoute objectForKey:#"legs"] objectAtIndex:0];
NSDictionary *end_location = [leg objectForKey:#"end_location"];
NSLog(#"dDDDDDD>>>>>>%#",leg);
double latitude = [[end_location objectForKey:#"lat"] doubleValue];
double longitude = [[end_location objectForKey:#"lng"] doubleValue];
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude);
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = coordinate;
point.title = [leg objectForKey:#"end_address"];
point.subtitle = #"I'm here!!!";
[self.mapview addAnnotation:point];
NSArray *steps = [leg objectForKey:#"steps"];
int stepIndex = 0;
CLLocationCoordinate2D stepCoordinates[1 + [steps count] + 1];
stepCoordinates[stepIndex] = userLocation.coordinate;
for (NSDictionary *step in steps) {
NSDictionary *start_location = [step objectForKey:#"start_location"];
stepCoordinates[++stepIndex] = [self coordinateWithLocation:start_location];
if ([steps count] == stepIndex){
NSDictionary *end_location = [step objectForKey:#"end_location"];
stepCoordinates[++stepIndex] = [self coordinateWithLocation:end_location];
}
}
MKPolyline *polyLine = [MKPolyline polylineWithCoordinates:stepCoordinates count:1 + stepIndex];
[mapview addOverlay:polyLine];
CLLocationCoordinate2D centerCoordinate = CLLocationCoordinate2DMake((userLocation.location.coordinate.latitude + coordinate.latitude)/2, (userLocation.location.coordinate.longitude + coordinate.longitude)/2);
}];
}
then implement the MKMapViewDelegate's method -(MKOverlayView *)mapView:viewForOverlay:
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
MKPolylineView *polylineView = [[MKPolylineView alloc] initWithPolyline:overlay];
polylineView.strokeColor = [UIColor colorWithRed:204/255. green:45/255. blue:70/255. alpha:1.0];
polylineView.lineWidth = 1;
return polylineView;
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
static NSString *annotaionIdentifier=#"annotationIdentifier";
MKPinAnnotationView *aView=(MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:annotaionIdentifier ];
if (aView==nil) {
aView=[[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:annotaionIdentifier];
aView.pinColor = MKPinAnnotationColorRed;
aView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
// aView.image=[UIImage imageNamed:#"arrow"];
aView.animatesDrop=TRUE;
aView.canShowCallout = YES;
aView.calloutOffset = CGPointMake(-5, 5);
}
return aView;
}
First of all Add frame work
1 Foundation.framework
2 CoreGraphics.framework
3 CoreLocation.framework
4 MapKit.framework
Then create nsobject file Like see.... TrailsMap.h File
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface TrailsMap : NSObject<MKAnnotation>
{
CLLocationCoordinate2D coordinate;
NSString *title;
NSString *image;
NSString *subtitle;
}
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
#property (nonatomic,copy) NSString *title;
#property (nonatomic,copy) NSString *image;
#property (nonatomic,copy) NSString *subtitle;
- (id)initWithLocation:(CLLocationCoordinate2D)coord;
TrailsMap.m
#import "TrailsMap.h"
#implementation TrailsMap
#synthesize coordinate,title,image,subtitle;
- (id)initWithLocation:(CLLocationCoordinate2D)coord{
self = [super init];
if (self) {
coordinate = coord;
}
return self;
}
Now Create coding in mainview Please see..
ViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface ViewController : UIViewController<MKMapViewDelegate>
#property (strong, nonatomic) IBOutlet MKMapView *MapView;
#property (nonatomic, retain) MKPolyline *routeLine;
#property (nonatomic, retain) MKPolylineView *routeLineView;
-(void)LoadMapRoute;
#end
Finally create coding in mainview.m file
ViewController.m
#import "ViewController.h"
#import "TrailsMap.h"
#interface ViewController ()
{
NSData *alldata;
NSMutableDictionary *data1;
NSMutableArray *RouteLocation;
NSMutableArray *RouteName;
}
#end
#implementation ViewController
#synthesize MapView,routeLine,routeLineView;
- (void)viewDidLoad
{
[super viewDidLoad];
RouteName = [[NSMutableArray alloc] initWithObjects:#"Ahmedabad",#"Rajkot", nil];
RouteLocation = [[NSMutableArray alloc] initWithObjects:#"23.0300,72.5800",#"22.3000,70.7833", nil];
[self LoadMapRoute];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
//-------------------------------------
// ************* Map ******************
//-------------------------------------
-(void)LoadMapRoute
{
MKCoordinateSpan span = MKCoordinateSpanMake(0.8, 0.8);
MKCoordinateRegion region;
region.span = span;
region.center= CLLocationCoordinate2DMake(23.0300,72.5800);
// Distance between two address
NSArray *coor1=[[RouteLocation objectAtIndex:0] componentsSeparatedByString:#","];
CLLocation *locA = [[CLLocation alloc] initWithLatitude:[[coor1 objectAtIndex:0] doubleValue] longitude:[[coor1 objectAtIndex:1] doubleValue]];
NSArray *coor2=[[RouteLocation objectAtIndex:1] componentsSeparatedByString:#","];
CLLocation *locB = [[CLLocation alloc] initWithLatitude:[[coor2 objectAtIndex:0] doubleValue] longitude:[[coor2 objectAtIndex:1] doubleValue]];
CLLocationDistance distance = [locA distanceFromLocation:locB];
NSLog(#"Distance :%.0f Meters",distance);
NSString *baseUrl = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/directions/json?origin=%#&destination=%#&sensor=true", [RouteLocation objectAtIndex:0],[RouteLocation objectAtIndex:1] ];
NSURL *url = [NSURL URLWithString:[baseUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
alldata = [[NSData alloc] initWithContentsOfURL:url];
NSError *err;
data1 =[NSJSONSerialization JSONObjectWithData:alldata options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves error:&err];
if (err)
{
NSLog(#" %#",[err localizedDescription]);
}
NSArray *routes = [data1 objectForKey:#"routes"];
NSDictionary *firstRoute = [routes objectAtIndex:0];
NSDictionary *leg = [[firstRoute objectForKey:#"legs"] objectAtIndex:0];
NSArray *steps = [leg objectForKey:#"steps"];
int stepIndex = 0;
CLLocationCoordinate2D stepCoordinates[[steps count]+1 ];
for (NSDictionary *step in steps)
{
NSDictionary *start_location = [step objectForKey:#"start_location"];
double latitude = [[start_location objectForKey:#"lat"] doubleValue];
double longitude = [[start_location objectForKey:#"lng"] doubleValue];
stepCoordinates[stepIndex] = CLLocationCoordinate2DMake(latitude, longitude);
if (stepIndex==0)
{
TrailsMap *point=[[TrailsMap alloc] initWithLocation:stepCoordinates[stepIndex]];
point.title =[RouteName objectAtIndex:0];
point.subtitle=[NSString stringWithFormat:#"Distance :%.0f Meters",distance];
[self.MapView addAnnotation:point];
}
if (stepIndex==[steps count]-1)
{
stepIndex++;
NSDictionary *end_location = [step objectForKey:#"end_location"];
double latitude = [[end_location objectForKey:#"lat"] doubleValue];
double longitude = [[end_location objectForKey:#"lng"] doubleValue];
stepCoordinates[stepIndex] = CLLocationCoordinate2DMake(latitude, longitude);
TrailsMap *point=[[TrailsMap alloc] initWithLocation:stepCoordinates[stepIndex]];
point.title = [RouteName objectAtIndex:1];
point.subtitle=[NSString stringWithFormat:#"Distance :%.0f Meters",distance];
[self.MapView addAnnotation:point];
}
stepIndex++;
}
MKPolyline *polyLine = [MKPolyline polylineWithCoordinates:stepCoordinates count: stepIndex];
[MapView addOverlay:polyLine];
[MapView setRegion:region animated:YES];
}
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
MKPolylineView *polylineView = [[MKPolylineView alloc] initWithPolyline:overlay];
polylineView.strokeColor = [UIColor colorWithRed:204/255. green:45/255. blue:70/255. alpha:1.0];
polylineView.lineWidth = 5;
return polylineView;
}
If You want to set multiple pin in map then just add this code.
Annotaion is Objectfile.
-(void)LoadMultiplePin
{
RouteName = [[NSMutableArray alloc] initWithObjects:#"Ahmedabad",#"Rajkot",#"Limdi", nil];
RouteLocation = [[NSMutableArray alloc] initWithObjects:#"23.0300,72.5800",#"22.3000,70.7833",#"22.5728,71.8114", nil];
MKCoordinateSpan span = MKCoordinateSpanMake(2.9, 2.9);
MKCoordinateRegion region;
region.span = span;
region.center= CLLocationCoordinate2DMake(22.5728,71.8114);
int cnt=RouteLocation.count;
for (int p=0 ; p<cnt ; p++ )
{
NSArray *coor=[[RouteLocation objectAtIndex:p] componentsSeparatedByString:#","];
CLLocationCoordinate2D location=CLLocationCoordinate2DMake([[coor objectAtIndex:0] doubleValue],[[coor objectAtIndex:1] doubleValue]);
Annotaion *point=[[Annotaion alloc] initWithLocation:location];
point.title =[RouteName objectAtIndex:p];
[Map addAnnotation:point];
}
[Map setRegion:region animated:YES];
}
By using this code You can easily Drope two pin and draw line between that two Pin
Enjoy Happy Coding...:)
I took the great answer from #graver and did this for Swift 3:
// Called from viewDidLoad
func setupMap() {
mapView.delegate = self
// BusStop implements the MKAnnotation protocol, I have an array of them
let routeCoordinates = busStops.map({ $0.coordinate })
let routeLine = MKPolyline(coordinates: routeCoordinates, count: routeCoordinates.count)
mapView.setVisibleMapRect(routeLine.boundingMapRect, animated: false)
mapView.add(routeLine)
}
// MARK: MKMapViewDelegate
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if let polyline = overlay as? MKPolyline {
let polylineRenderer = MKPolylineRenderer(overlay: polyline)
polylineRenderer.strokeColor = .blue
polylineRenderer.lineWidth = 3
return polylineRenderer
}
return MKOverlayRenderer(overlay: overlay)
}
I have created demo in swift with continue update location on map with polyline.
Please follow below steps :
1) Create new project and set up required things.
2) Go to project target->Build Phases -> Link Binary with Libraries and add
MapKit.framwork, CoreLocation.framework.
3) Go to sotryboard and add mapview and linkup with your viewcontroller.
4) Add properties and delegates that i am providing code below.
ViewController.Swift
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController,CLLocationManagerDelegate,MKMapViewDelegate{
#IBOutlet weak var mapView:MKMapView!
var locationManager: CLLocationManager!
var routeArr:[CLLocationCoordinate2D] = []
var isStarted:Bool = false
// MARK:- Life cycle
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.delegate = self;
locationManager.startMonitoringSignificantLocationChanges()
locationManager.allowsBackgroundLocationUpdates = true
locationManager.pausesLocationUpdatesAutomatically = false
// user activated automatic authorization info mode
let status = CLLocationManager.authorizationStatus()
if status == .notDetermined || status == .denied || status == .authorizedWhenInUse {
// present an alert indicating location authorization required
// and offer to take the user to Settings for the app via
// UIApplication -openUrl: and UIApplicationOpenSettingsURLString
locationManager.requestAlwaysAuthorization()
locationManager.requestWhenInUseAuthorization()
}
locationManager.startUpdatingLocation()
locationManager.startUpdatingHeading()
mapView.delegate = self
mapView.showsUserLocation = true
mapView.mapType = MKMapType(rawValue: 0)!
mapView.userTrackingMode = MKUserTrackingMode(rawValue: 2)!
}
// MARK:- Button Actions
#IBAction func startBtnClick(_ sender: Any) {
isStarted = true
}
#IBAction func endBtnClick(_ sender: Any) {
isStarted = false
routeArr.removeAll()
}
// MARK:- LocationManager Delegate
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
if isStarted == true {
if locations.count > 0 {
let newLocation:CLLocationCoordinate2D = (location?.coordinate ?? nil)!
routeArr.append(newLocation)
DispatchQueue.main.async {
if self.routeArr.count > 2 {
let route:[CLLocationCoordinate2D] = [self.routeArr[self.routeArr.count - 2] ,self.routeArr.last!]
print(route)
let polyline = MKPolyline(coordinates: route, count: route.count)
self.mapView.addOverlay(polyline)
}
}
}
}
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if (overlay is MKPolyline) {
let pr = MKPolylineRenderer(overlay: overlay)
pr.strokeColor = UIColor.red
pr.fillColor = .green
pr.lineWidth = 5
return pr
}else {
return MKOverlayRenderer()
}
}
}
Run your project and click on start button for tracking and you can see polyline on map. If you click on stop button then it will stop to draw polyline.
Thankyou
pass your address cordination
-(NSArray*) calculateRoutesFrom:(CLLocationCoordinate2D) f to: (CLLocationCoordinate2D) t {
NSString* saddr = [NSString stringWithFormat:#"%f,%f", f.latitude, f.longitude];
NSString* daddr = [NSString stringWithFormat:#"%f,%f", t.latitude, t.longitude];
NSString* apiUrlStr = [NSString stringWithFormat:#"http://maps.google.com/maps? output=dragdir&saddr=%#&daddr=%#", saddr, daddr];
// NSString* apiUrlStr = #"http://maps.google.com/maps?output=dragdir&saddr=40.769264,-73.958995&daddr=47.286522,-122.312932";
NSURL* apiUrl = [NSURL URLWithString:apiUrlStr];
NSLog(#"api url: %#", apiUrl);
NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl encoding:NSUTF8StringEncoding error:nil];
NSString* encodedPoints = [apiResponse stringByMatching:#"points:\\\"([^\\\"]*)\\\"" capture:1L];
return [self decodePolyLine:[encodedPoints mutableCopy]];
}
-(NSMutableArray *)decodePolyLine: (NSMutableString *)encoded {
[encoded replaceOccurrencesOfString:#"\\\\" withString:#"\\"
options:NSLiteralSearch
range:NSMakeRange(0, [encoded length])];
NSInteger len = [encoded length];
NSInteger index = 0;
NSMutableArray *array = [[NSMutableArray alloc] init];
NSInteger lat=0;
NSInteger lng=0;
while (index < len) {
NSInteger b;
NSInteger shift = 0;
NSInteger result = 0;
do {
b = [encoded characterAtIndex:index++] - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
NSInteger dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = [encoded characterAtIndex:index++] - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
NSInteger dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
lng += dlng;
NSNumber *latitude = [[NSNumber alloc] initWithFloat:lat * 1e-5];
NSNumber *longitude = [[NSNumber alloc] initWithFloat:lng * 1e-5];
printf("[%f,", [latitude doubleValue]);
printf("%f]", [longitude doubleValue]);
CLLocation *loc = [[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]];
[array addObject:loc];
}
return array;
}
-(void) updateRouteView:(UIColor *)clr {
CGContextRef context =CGBitmapContextCreate(nil,routeView.frame.size.width,routeView.frame.size.height,8,4 * routeView.frame.size.width,CGColorSpaceCreateDeviceRGB(), kCGImageAlphaPremultipliedLast);
CGContextSetStrokeColorWithColor(context, clr.CGColor);
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);
CGContextSetLineWidth(context, 3.0);
for(int i = 0; i < routes.count; i++) {
CLLocation* location = [routes objectAtIndex:i];
CGPoint point = [mapView convertCoordinate:location.coordinate toPointToView:routeView];
if(i == 0) {
CGContextMoveToPoint(context, point.x, routeView.frame.size.height - point.y);
} else {
CGContextAddLineToPoint(context, point.x, routeView.frame.size.height - point.y);
}
}
CGContextStrokePath(context);
CGImageRef image = CGBitmapContextCreateImage(context);
UIImage* img = [UIImage imageWithCGImage:image];
routeView.image = img;
CGContextRelease(context);
}
You can draw lines in map using MKPolyline.
See this link
http://spitzkoff.com/craig/?p=136
ALSO:
https://github.com/kishikawakatsumi/MapKit-Route-Directions
http://cloudmade.com/
These are all tutorials and open source libraries which you can easily refer to. Currently MapKit does not support this feature...
here you must calculate the route with its latitude and longtitude and then draw the poly line on MapView........
I do this things in my app....i draw route on mapview with all information....
here if you MapKit and also use RagexKitLite then its too simple for you just get Demo of RagexKitLite....
Get full code:https://github.com/javedmultani16/MapKitWithPolyLine
Draw line like:
directionsRequest.transportType = MKDirectionsTransportType.automobile
//Draw polyline by using MKRoute so it follows the street roads...
for (k, item) in arrayarrayPlacemarks.enumerated() {
if k < (arrayarrayPlacemarks.count - 1) {
directionsRequest.source = item
directionsRequest.destination = arrayarrayPlacemarks[k+1]
let directions = MKDirections(request: directionsRequest)
directions.calculate { (response:MKDirections.Response!, error: Error!) -> Void in
if error == nil {
self.locRoute = response.routes[0] as? MKRoute
let geodesic:MKPolyline = self.locRoute!.polyline
self.mapView.addOverlay(geodesic)
}
}
}
}
Delegate method :
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay.isKind(of: MKPolyline.self){
var polylineRenderer = MKPolylineRenderer(overlay: overlay)
polylineRenderer.fillColor = UIColor.blue
polylineRenderer.strokeColor = UIColor.blue
polylineRenderer.lineWidth = 2
return polylineRenderer
}
return MKOverlayRenderer(overlay: overlay)
}

Issue in Displaying Multiple annonations view in MkMapKit

I need to display multiple annonation views in MKMapKit..I use this code..
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
DisplayMap *ann = [[DisplayMap alloc] init];
//NSLog(#"xapp.arrplacename:%d",[xapp.arrplacename count]);
for (i=0;i<=[arrplacename count]-1;i++)
{
MKCoordinateRegion region = { {0.0, 0.0 }, { 0.0, 0.0 } };
//arrplacename contains the address of the locations
NSString *straddress=[arrplacename objectAtIndex:i];
NSString *strregion=#"";
NSString *strs=[straddress stringByAppendingString: strregion];
// lbladdress.text=strs;
// NSString add=strs;
// here you define the url setting your address
NSString *urlString = [NSString stringWithFormat:#"http://maps.google.com/maps/geo?q=%#&output=csv",[strs stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
NSLog(#"US: %#",urlString);
// then you get the response string here
NSString *locationString = [[[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:urlString]] autorelease];
NSLog(#"loaction strings%#",locationString);
// now you can create an array splitting the response values using the ","
//[listItems addObject:locationString];
listItems = [locationString componentsSeparatedByString:#","];
NSLog(#"A: %#",[xapp.listItems objectAtIndex:2]);
// define latitude and longitude variables
double latitude = 0.0;
double longitude = 0.0;
NSString *strlatitude;
NSString *strlongitude;
strlatitude=[xapp.listItems objectAtIndex:2];
strlongitude=[xapp.listItems objectAtIndex:3];
float stringFloat = [strlatitude floatValue];
float string1Float = [strlongitude floatValue];
// if your array has inside the sctructure you aspect (4 values as described in my previous post) and the first value is like "200" (OK result)
if([xapp.listItems count] >= 4 && [[xapp.listItems objectAtIndex:0] isEqualToString:#"200"])
{
// not sure if you need the accurancy parameter
//accurancy = [[listItems objectAtIndex:1] intValue];
// here you can get your values
// latitude = [[listItems objectAtIndex:2] doubleValue];
//longitude = [[listItems objectAtIndex:3] doubleValue];
latitude = stringFloat;
longitude = string1Float;
}
else {
NSLog(#"Error on map");
}
region.center.latitude = latitude;
region.center.longitude = longitude;
NSLog(#"latitude:%g",region.center.latitude);
// region.center.latitude = 42.7157850;
// region.center.longitude = 27.56470180;
region.span.longitudeDelta = 0.01f;
region.span.latitudeDelta = 0.01f;
[mapView setRegion:region animated:YES];
[mapView setDelegate:self];
ann.title = [xapp.arrplacename objectAtIndex:i];
ann.subtitle = [xapp.arrplacename objectAtIndex:i];
ann.coordinate = region.center;
[mapView addAnnotation:ann];
}
}
I do have some problems in this code....all the coordnates are not added to the listitems array..I can see only the objects that are added atlast....
This is the delegates I add for displaying the annonation in my map..
- (CLLocationCoordinate2D) geoCodeUsingAddress:(NSString *)address{
NSLog(#"ssssss");
double latitude = 0, longitude = 0;
NSString *esc_addr = [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *req = [NSString stringWithFormat:#"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%#", esc_addr];
NSString *result = [NSString stringWithContentsOfURL:[NSURL URLWithString:req] encoding:NSUTF8StringEncoding error:NULL];
if (result) {
NSScanner *scanner = [NSScanner scannerWithString:result];
if ([scanner scanUpToString:#"\"lat\":" intoString:nil] && [scanner scanString:#"\"lat\":" intoString:nil]) {
[scanner scanDouble:&latitude];
if ([scanner scanUpToString:#"\"lng\":" intoString:nil] && [scanner scanString:#"\"lng\":" intoString:nil]) {
[scanner scanDouble:&longitude];
}
}
}
CLLocationCoordinate2D center;
center.latitude = latitude;
center.longitude = longitude;
return center;
}
-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:
(id <MKAnnotation>)annotation {
MKPinAnnotationView *pinView = nil;
NSLog(#"pinnview before release %d",[pinView retainCount]);
if (pinView !=nil) {
pinView =nil;
[pinView release];
}
NSLog(#"pinnview after release %d",[pinView retainCount]);
// if it's the user location, just return nil.
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
if(annotation != mapView.userLocation)
{
static NSString *defaultPinID = #"your-pin";
pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( counting < [mapView.annotations count])
{
counting++;
pinView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];
/* for(DisplayMap* a in mapView.annotations)
{
if (annotation == a){
pinView.image =
[UIImage imageWithContentsOfFile:
[[NSBundle mainBundle] pathForResource:a.image ofType:nil]];
}
}*/
pinView.centerOffset= CGPointMake(0,-10);
pinView.canShowCallout = YES;
}
}
// return pinView;
}
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
NSLog(#"enter");
[mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];
}
Delegates are called only once eventhough I'm using [mapView addAnnotation:ann]; inside the for loop...And it shows pin only for the last item tatz added in the array...How can I overcome this????
You are allocating and initializing 'ann' only once before the for loop starts, and you are altering the same and adding it again and again into Map. Thats why you are getting only one annotation.
Move this line inside for loop and try,
DisplayMap *ann = [[DisplayMap alloc] init];

- (MKAnnotationView *)mapView not getting called

In my code, the - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation method is not getting called. I don know why. Can anyone please help me?
Below is my code:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#","];
NSLog(#"pin map");
if(pinView == nil)
{
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#""];
pinView.animatesDrop = YES;
pinView.canShowCallout = YES;
UIImage *image = [UIImage imageNamed:#"ann.png"];
CGRect resizeRect;
resizeRect.size = image.size;
CGSize maxSize = CGRectInset(self.view.bounds,
[map annotationPadding],
[map annotationPadding]).size;*/
maxSize.height -= self.navigationController.navigationBar.frame.size.height + [map 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);
[image drawInRect:resizeRect];
UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
pinView.image = resizedImage;
pinView.opaque = NO;
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:self
action:#selector(showDetails:)
forControlEvents:UIControlEventTouchUpInside];
pinView.rightCalloutAccessoryView = rightButton;
if (annotation == mapView.userLocation)
{
return nil;
}
return pinView;
}
else
{
pinView.annotation = annotation;
}
return pinView;
}
This is how I am adding the annotations to the map:
-(void) Annotations:(int)i
{
/*NSString* address = [mpartyDetail objectAtIndex:i];
address = [[address componentsSeparatedByCharactersInSet: [NSCharacterSet whitespaceCharacterSet]] componentsJoinedByString: #""];
NSString *urlString = [NSString stringWithFormat:#"http://maps.google.com/maps/geo?q=%#&output=csv", address];
NSLog(#"nsstring %#",urlString);
NSString *locationString = [[[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:urlString]] autorelease];
NSLog(#"location string %#",locationString);
NSArray *latlng = [locationString componentsSeparatedByString:#","];
NSLog(#"the latlng %#",latlng);
float lat = [[latlng objectAtIndex:2] floatValue];
float lng = [[latlng objectAtIndex:3] floatValue]; */
NSLog(#"ann");
lat = [[latiArray objectAtIndex:i]floatValue];
lng = [[longiArray objectAtIndex:i]floatValue];
CLLocationCoordinate2D newCoord = {lat,lng};
mapAnnotations* annotation = [[mapAnnotations alloc] initWithCoordinate:newCoord];
[mapView addAnnotation:annotation];
}
mapAnnotations is another class. The below code shows the method of that class which is getting called:
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate{
NSLog(#"the cor");
self = [super init];
if (self != nil) {
NSLog(#"in");
_coordinate = coordinate;
}
return self;
}
The idea is that I add annotations when the user presses on the map and the user can give any title to that pin. I need a callout to show the title entered by the user. The annotations are getting added. But I am not able to get the callout as this method is not getting called.
Did you assign the class containing that method as the delegate for your map view, did you actually add any annotations to the map view, and are the locations for those annotations actually visible in the portion of the map currently displayed on-screen?
as someone rightly pointed out the delegate wasnt set to the same class in my case
all i did was in the code where i add annotation i wrote the code:
mapView.delegate=self;
and it worked great for me.
if you didnt do that do it and it might work for you also droid.
How are you adding annotations to your map? I use the following
while(some condition){
MapAnnotation *annotation = [[MapAnnotation alloc] initWithLatitude:(float)goLat Longitude:(float)goLng title:(NSString*)recallTask.blurb subtitle:(NSString*)recallTask.location];
[appDelegate.annArray addObject:annotation];
[annotation release];
annotation = nil;
}
[self.mapView addAnnotations:appDelegate.annArray];

Reload JSON Feed within a UIView

I have a mapView that has annotation added through JSON (feed is stored in NSDictionary). Everything works great, but I want to add a feature.
I want the mapView to reload all of the annotations each time the view reappears (every time the tab bar is pressed). T've tried putting the part where the JSON is added to the NSDictionary in viewWillAppear {} .... but it does not work.
My code is below. Thanks in advance!
#import "MapViewController.h"
#import "DisplayMap.h"
#import "JSON/JSON.h"
#implementation MapViewController
#synthesize mapView;
#synthesize selectedType;
#synthesize locationManager;
// JSON from Server Actions
- (NSString *)stringWithUrl:(NSURL *)url {
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReturnCacheDataElseLoad
timeoutInterval:30];
// Fetch the JSON response
NSData *urlData;
NSURLResponse *response;
NSError *error;
// Make synchronous request
urlData = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
// Construct a String around the Data from the response
return [[NSString alloc] initWithData:urlData encoding:NSUTF8StringEncoding];
}
- (id)objectWithUrl:(NSURL *)url {
SBJsonParser *jsonParser = [SBJsonParser new];
NSString *jsonString = [self stringWithUrl:url];
// Parse the JSON into an Object
return [jsonParser objectWithString:jsonString error:NULL];
}
- (NSDictionary *) downloadFeed {
id response = [self objectWithUrl:[NSURL URLWithString:#"http://www.example.com/JSON"]];
NSDictionary *feed = (NSDictionary *)response;
return feed;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locationManager startUpdatingLocation];
mapView.mapType = MKMapTypeStandard;
mapView.zoomEnabled = YES;
mapView.scrollEnabled = YES;
mapView.showsUserLocation = YES;
MKCoordinateRegion region = { {0.0, 0.0 }, { 0.0, 0.0 } };
region.span.longitudeDelta = 0.005;
region.span.latitudeDelta = 0.005;
[mapView setRegion:region animated:YES];
[mapView setDelegate:self];
// Download JSON Feed
NSDictionary *feed = [self downloadFeed];
NSArray *streams = (NSArray *)[feed valueForKey:#"stream"];
int Info;
for (Info = 0; Info < streams.count; Info++) {
NSDictionary *stream = (NSDictionary *)[streams objectAtIndex:Info];
NSLog(#"Time: %#", [stream valueForKey:#"Time"]);
NSLog(#"Type: %#", [stream valueForKey:#"Type"]);
NSLog(#"Longitude: %#", [stream valueForKey:#"Longitude"]);
NSLog(#"Latitude: %#", [stream valueForKey:#"Latitude"]);
double lat = [[stream valueForKey:#"Latitude"] doubleValue];
double lon = [[stream valueForKey:#"Longitude"] doubleValue];
NSString *ttype = [[NSString alloc] initWithFormat: #"%#", [stream valueForKey:#"Type"]];
selectedType = ttype;
CLLocationCoordinate2D coord = {lat, lon};
DisplayMap *ann = [[DisplayMap alloc] init];
ann.title = [NSString stringWithFormat: #"%#", [stream valueForKey:#"Type"]];
ann.subtitle = [NSString stringWithFormat: #"%#", [stream valueForKey:#"Time"]];
ann.coordinate = coord;
[mapView addAnnotation:ann];
}
}
}
}
-(void)viewWillAppear { }
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
CLLocationCoordinate2D loc = [newLocation coordinate];
[mapView setCenterCoordinate:loc];
}
-(IBAction)refreshMap:(id)sender {
// Download JSON Feed
NSDictionary *feed = [self downloadFeed];
NSArray *streams = (NSArray *)[feed valueForKey:#"stream"];
int Info;
for (Info = 0; Info < streams.count; Info++) {
NSDictionary *stream = (NSDictionary *)[streams objectAtIndex:Info];
NSLog(#"Time: %#", [stream valueForKey:#"Time"]);
NSLog(#"Type: %#", [stream valueForKey:#"Type"]);
NSLog(#"Longitude: %#", [stream valueForKey:#"Longitude"]);
NSLog(#"Latitude: %#", [stream valueForKey:#"Latitude"]);
double lat = [[stream valueForKey:#"Latitude"] doubleValue];
double lon = [[stream valueForKey:#"Longitude"] doubleValue];
NSString *ttype = [[NSString alloc] initWithFormat: #"%#", [stream valueForKey:#"Type"]];
selectedType = ttype;
CLLocationCoordinate2D coord = {lat, lon};
DisplayMap *ann = [[DisplayMap alloc] init];
ann.title = [NSString stringWithFormat: #"%#", [stream valueForKey:#"Type"]];
ann.subtitle = [NSString stringWithFormat: #"%#", [stream valueForKey:#"Time"]];
ann.coordinate = coord;
[mapView addAnnotation:ann];
}
}
-(MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation {
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil; //return nil to use default blue dot view
static NSString *AnnotationViewID = #"annotationViewID";
MKAnnotationView *annotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
if (annotationView == nil) {
annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID] autorelease];
}
annotationView.canShowCallout = YES;
if ([annotationView.annotation.title isEqualToString:#"Selected"]) {
UIImage *pinImage = [UIImage imageNamed:#"icon_selected.png"];
[annotationView setImage:pinImage];
}
annotationView.annotation = annotation;
return annotationView;
}
- (void)dealloc {
[mapView release];
self.adView.delegate = nil;
self.adView = nil;
[super dealloc];
}
#end
From UIViewController.h:
- (void)viewWillAppear:(BOOL)animated;
viewWillAppear is not the same as viewWillAppear:. Perhaps if you override the proper method it might work?
I think more details are needed. If viewWillAppear is not getting called then it is probably something to do with the way you are setting up the views.
These two links should give you some pointers.
How do I have a view controller run updating code when it is brought to the top of the stack of views?
and
What's the proper way to add a view controller to the view hierarchy?

mapkit , tagging a disclosure button with index of annotation

i have been struggling with this for a few days, i even re-wrote half the code to try it another way.
i have my annotations imported from a csv, and placed onto the map with tile and subtitle, i am trying in vain to add a tag to disclosue buttons so i can see which one was tapped, but having problems, whatever values i assign to the annotation i cant seem to access them (like the index) i can access the title and subtitle, but thats it.
how do i assign a index to the annotation that i can then add to the button as a tag, so i can record the tap
here is my code
NSURL *dataUrl = [NSURL URLWithString:#"http://nne.ezadspro.co.uk/cms/testmap.txt"];
// URLWithString:#"http://neic.usgs.gov/neis/gis/qed.asc"];
NSString *fileString = [NSString stringWithContentsOfURL:dataUrl
encoding:NSUTF8StringEncoding
error:nil];
int count = 0;
NSScanner *scanner = [NSScanner scannerWithString:fileString];
points = [[NSMutableArray array] retain];
AnnotationData *event;
NSString *line;
NSArray *values;
while ([scanner isAtEnd] == NO) {
[scanner scanUpToString:#"\n" intoString:&line];
//skip the first line
if(count > 0) {
values = [line componentsSeparatedByString:#","];
event = [[[AnnotationData alloc] init] autorelease];
event.latitude = [[values objectAtIndex:5] floatValue];
event.longitude = [[values objectAtIndex:6] floatValue];
event.companyID = [[values objectAtIndex:0]intValue];
event.title = [values objectAtIndex:1];
event.subtitle = [values objectAtIndex:2];
//event.magnitude = [[values objectAtIndex:4] floatValue];
//event.depth = [[values objectAtIndex:5] floatValue];
//NSLog(#"%#",event.companyID);
[points addObject:event];
}
count++;
if(count == 300) {
//limit number of events to 300
break;
}
}
for (int i=0; i<points.count; i++) {
AnnotationData *annData = [points objectAtIndex:i];
coordinate.latitude = annData.latitude;
coordinate.longitude = annData.longitude;
CLLocationCoordinate2D newCoord = {coordinate.latitude, coordinate.longitude};
PlaceAnnotation* annotation = [[PlaceAnnotation alloc] initWithCoordinate:newCoord andID:i];
annotation.mTitle = annData.title;
annotation.mSubtitle = annData.subtitle;
annotation.indexID = i;
//annotation.indexID = [[i]intValue];
[mapView addAnnotation:annotation];
[annotation release];
}
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation
{
MKPinAnnotationView *pinAnnotation = nil;
if(annotation != mV.userLocation)
{
static NSString *defaultPinID = #"myPin";
pinAnnotation = (MKPinAnnotationView *)[mV dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinAnnotation == nil )
pinAnnotation = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];
pinAnnotation.canShowCallout = YES;
//instatiate a detail-disclosure button and set it to appear on right side of annotation
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinAnnotation.rightCalloutAccessoryView = infoButton;
//infoButton.tag =
//[infoButton addTarget:self action:#selector(onMapVenueSelect) forControlEvents:UIControlEventTouchUpInside];
//defaultPinID.rightCalloutAccessoryView = infoButton;
//infoButton.tag = [event indexOfObject:tmpVenueData];
// [defaultPinID release];
}
return pinAnnotation;
[pinAnnotation release];
}
thanks
Consider using the MKAnnotation protocol and storing whatever you need ID or data wise your object.
A starting point header might go something like this:
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface YourFancyAnnotationClass : NSObject <MKAnnotation> {
CLLocationCoordinate2D coordinate;
NSString *title;
NSString *subtitle;
NSNumber *companyID;
}
#property(nonatomic, assign) CLLocationCoordinate2D coordinate;
#property(nonatomic, copy) NSString *title;
#property(nonatomic, copy) NSString *subtitle;
#property(nonatomic, copy) NSNumber *companyID;
#end
Then in your delegate do something like this...
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
NSLog(#"calloutAccessoryControlTapped:");
YourFancyAnnotationClass *tappedSite = (SiteAnnotation *)[view annotation];
NSNumber *companyIDThatWasClickedExample = [tappedSite companyID];
etc...