I have an array which stores data from webservice. The data contains multiple locations.
The array updates when the map center is moved. It shows pins based on map center. What i want to do is to remove those old pins that i have allotted on the map without removing all the markers and if new pins are stored, allot them without adding all of them again.
Thanks in advance.
Here is my code.
if ([tempOLDArr count]>0) {
for (int i = 0; i<[appdelegate.eventsArray count]; i++) {
eventsWebService *temp = [appdelegate.eventsArray objectAtIndex:i];
if (i<[tempOLDArr count]) {
if ([temp.eventID isEqualToString:[[tempOLDArr objectAtIndex:i]eventID]]) {
}
else {
[tempNEWArr addObject:[appdelegate.eventsArray objectAtIndex:i] ];
}
}
else if(i>=[tempOLDArr count]){
[tempNEWArr addObject:[appdelegate.eventsArray objectAtIndex:i] ];
}
}
if ([tempNEWArr count]>0) {
[self creatingAnnotation:tempNEWArr];
}
}
else {
tempOLDArr = appdelegate.eventsArray;
[self creatingAnnotation:tempOLDArr];
}
And here is my code for plotting those markers
-(void)creatingAnnotation:(NSArray *) eventsArr{
for(int i=0;i<[eventsArr count];i++)
{
HomeEventLat = [[appdelegate.eventsArray objectAtIndex:i]eventLat];
HomeEventlong = [[appdelegate.eventsArray objectAtIndex:i]eventLong];
double pickuplat = [HomeEventLat doubleValue];
double pickuplng = [HomeEventlong doubleValue];
CLLocation * loca=[[CLLocation alloc]initWithLatitude:pickuplat longitude:pickuplng];
CLLocationCoordinate2D coordi=loca.coordinate;
eventMarker = [[CustomGoogleMarker alloc]init];
eventMarker.position = CLLocationCoordinate2DMake(pickuplat, pickuplng);
eventMarker = [CustomGoogleMarker markerWithPosition:coordi];
eventMarker.snippet = NO;
eventMarker.icon = [UIImage imageNamed:#"map-pin-icon"];
eventMarker.tappable = YES;
eventMarker.marker_description = [[appdelegate.eventsArray objectAtIndex:i]eventDetail];
eventMarker.marker_distance = [[appdelegate.eventsArray objectAtIndex:i]eventdistance];
eventMarker.markerID = [[appdelegate.eventsArray objectAtIndex:i]eventID];
eventMarker.marker_joinedNo = [[appdelegate.eventsArray objectAtIndex:i]eventJoinedNo];
eventMarker.marker_price = [[appdelegate.eventsArray objectAtIndex:i]eventPrice];
eventMarker.marker_commentsNo = [[appdelegate.eventsArray objectAtIndex:i]eventCommentsNo];
eventMarker.marker_address = [[appdelegate.eventsArray objectAtIndex:i]eventAddress];
eventMarker.ID = [NSString stringWithFormat:#"%d",i];
// eventMarker.appearAnimation = kGMSMarkerAnimationPop;
NSString *markerLabels = [[appdelegate.eventsArray objectAtIndex:i]labelsList];
NSLog(#"%#",markerLabels);
eventMarker.marker_label = markerLabels;
eventMarker.marker_username = [[appdelegate.eventsArray objectAtIndex:i]user];
eventMarker.marker_time = [[appdelegate.eventsArray objectAtIndex:i]eventTime];
eventMarker.marker_image = [[appdelegate.eventsArray objectAtIndex:i]eventimage];
// eventMarker.title = [[appdelegate.eventsArray objectAtIndex:i]eventsID];
//
// [self.mapView clear];
eventMarker.map = self.mapView;
//
//
[markerDetail addObject:[appdelegate.eventsArray objectAtIndex:i]];
}
[_mapView animateWithCameraUpdate:[GMSCameraUpdate fitBounds:bounds withPadding:10]];
}
Related
i m showing user's location in a map view(apple map) with custom pin and those same pins are shown in a table view in front of the user name.Each user should have a different pin and if the user name occurs twice then it should have the same pin colour as the previous one.
This is the table view screen shot and below this table view there is a map view:
if in the table view "user name" has blue pin then in the map "username's" location shud be shown with blue pin.
if user2 has green pin in table, it should be green in map as well.
the response i m getting is
{
"driver_or_rider" = 1;
email = "ish#gmail.com";
isGuest = 0;
lat = "47.606209";
long = "-122.332071";
name = "ish bids";
"status_trip" = 1;
"user_image_url" = "http://app/image/1458101010.userimage";
},
{
"driver_or_rider" = 0;
email = "arin#gmail.com";
isGuest = 0;
lat = "34.052227";
long = "-118.243660";
name = "arin John";
"status_trip" = 1;
"user_image_url" = "http://app/image/5b3ee2e9fb51c7b20303a95b93bf63b2.";
},
{
"driver_or_rider" = 0;
email = "deepak12#gmail.com";
isGuest = 0;
lat = "31.968599";
long = "-99.901813";
name = "Deepak Chaudhary chaudhary ";
"status_trip" = 1;
"user_image_url" = "http://app/image/2197c75dc6b2bbd0ff26008a987781f3.";
},
{
"driver_or_rider" = 0;
email = "ish#gmail.com";
isGuest = 1;
lat = "31.968599";
long = "-99.901813";
name = "Deepak Chaudhary chaudhary 's Guest";
"status_trip" = 1;
"user_image_url" = "http://app/image/no-image.png";
},
{
"driver_or_rider" = 0;
email = "ish#gmail.com";
isGuest = 1;
lat = "41.878114";
long = "-87.629798";
name = "shiv Shankar 's Guest";
"status_trip" = 1;
"user_image_url" = "http://app/image/no-image.png";
},
{
"driver_or_rider" = 0;
email = "shiv#gmail.com";
isGuest = 0;
lat = "41.878114";
long = "-87.629798";
name = "shiv Shankar ";
"status_trip" = 1;
"user_image_url" = "http://app/image/1458129359.userimage";
},
{
"driver_or_rider" = 0;
email = "andrew.payasi#gmail.com";
isGuest = 0;
lat = "43.65322577127058";
long = "-79.38318371772766";
name = username;
"status_trip" = 1;
"user_image_url" = "http://app/image/1456821877.png";
}
)
this is the code in cell for row at index
int randomNumber = indexPath.row % [imageNameArray count];
NSString* nameStr=[goersInfo valueForKey:#"name"];
NSArray * nameStrArray = [nameStr componentsSeparatedByString: #"'s"];
nameStr=[nameStrArray objectAtIndex:0];
NSNumber *indexNumber = self.pinDictionary[nameStr];
index = indexNumber.unsignedIntegerValue;
cell.PinImageView.image=[UIImage imageNamed:[imageNameArray objectAtIndex:index]];
this is dictionary where name are stored
- (void)setupPinDictionary
{
self.pinDictionary = [NSMutableDictionary dictionary];
self.imageNameArray = [[NSArray alloc] initWithObjects:#"pin2#2x.png", #"pin3#2x.png", #"pin4#2x.png", #"pin5#2x.png", #"pin6#2x.png",#"pin8#2x.png",#"pin9#2x.png", nil];
NSUInteger pinImageCount = self.imageNameArray.count;
for (NSDictionary *goersInfo in tableGoersList) {
NSString* nameStr=[goersInfo valueForKey:#"name"];
NSArray * nameStrArray = [nameStr componentsSeparatedByString: #"'s"];
nameStr=[nameStrArray objectAtIndex:0];
if (self.pinDictionary[nameStr] == nil) {
indexPin = arc4random() % pinImageCount;
self.pinDictionary[nameStr] = [NSNumber numberWithUnsignedInteger: indexPin];
}
}
Initially this method is called
-(void)doJourneyGoersList:(id)responseObject{
NSDictionary *dict=[responseObject[#"Count"] firstObject];
checkLocation=[[NSMutableArray alloc]init];
if (dict==nil) {
return;
}
[_messagesButton.badgeButton setBadgeValue:dict[#"Count_Masssage"]];
[_invitesButton.badgeButton setBadgeValue:dict[#"invite_count"]];
[_matchedButton.badgeButton setBadgeValue:dict[#"Count_Match"]];
goersList= [responseObject objectForKey:#"statement"];
CLLocationCoordinate2D orginCllocation=CLLocationCoordinate2DMake([_tripDetails[#"origin_lat"] doubleValue], [_tripDetails[#"origin_long"] doubleValue]);
MKPointAnnotation *annotation =[[MKPointAnnotation alloc] init];
annotation.coordinate=orginCllocation;
[checkLocation addObject:annotation];
tableGoersList=[NSMutableArray new];
for (NSDictionary *dict in goersList) {
NSMutableDictionary *localdict=[NSMutableDictionary new];
loc=[NSMutableDictionary new];
[localdict setObject:[dict objectForKey:#"name"] forKey:#"name"];
[localdict setObject:[dict objectForKey:#"email"] forKey:#"email"];
if ([dict[#"status_trip"] isEqualToString:#"confirm"]) {
[localdict setObject:#"1" forKey:#"status_trip"];
[loc setObject:[dict objectForKey:#"origin_lat"] forKey:#"lat"];
[loc setObject:[dict objectForKey:#"origin_long"] forKey:#"long"];
CLLocationCoordinate2D location=CLLocationCoordinate2DMake([loc[#"lat"] doubleValue], [loc[#"long"] doubleValue]);
[localdict setObject:[dict objectForKey:#"origin_lat"] forKey:#"lat"];
[localdict setObject:[dict objectForKey:#"origin_long"] forKey:#"long"];
if (location.latitude == orginCllocation.latitude && location.longitude == orginCllocation.longitude) {
//location is origin, skip this since it is already added
} else {
MKPointAnnotation *annotation =[[MKPointAnnotation alloc] init];
annotation.coordinate=location;
[checkLocation addObject: annotation];
}
NSLog(#"check location %#",checkLocation);
}
else
[localdict setObject:#"0" forKey:#"status_trip"];
if ([dict[#"isGuest"] isEqualToString:#"1"]) {
[localdict setObject:#"1" forKey:#"isGuest"];
}
else
[localdict setObject:#"0" forKey:#"isGuest"];
[localdict setObject:[dict objectForKey:#"user_image_url"] forKey:#"user_image_url"];
if ([dict[#"driver_or_rider"] isEqualToString:#"Drive"]) {
[localdict setObject:#"1" forKey:#"driver_or_rider"];
[tableGoersList insertObject:localdict atIndex:0];
}
else
{
[localdict setObject:#"0" forKey:#"driver_or_rider"];
[tableGoersList addObject:localdict];
}
//add the objects to the array
}
CLLocationCoordinate2D parkCllocation=CLLocationCoordinate2DMake([_tripDetails[#"park_lat"] doubleValue], [_tripDetails[#"park_long"] doubleValue]);
MKPointAnnotation *jauntAnnotationPark =[[MKPointAnnotation alloc] init];
jauntAnnotationPark.coordinate=parkCllocation;
[checkLocation addObject:jauntAnnotationPark];
[mapView showAnnotations: checkLocation animated:NO];
[mapView setCenterCoordinate:mapView.region.center animated:NO];
int count = [checkLocation count];
CLLocationCoordinate2D coordinateArray[count];
for (int i = 0; i < count; i++) {
coordinateArray[i] = ((MKPointAnnotation *)checkLocation[i]).coordinate;
}
self.routeLine = [MKPolyline polylineWithCoordinates:coordinateArray count:count];
[mapView addOverlay:self.routeLine];
[self setupPinDictionary];
[self.ridersTableView reloadData];
}
and this is the code for view for annotation
{
imageNameArray = [[NSArray alloc] initWithObjects:#"pin2#2x.png", #"pin3#2x.png", #"pin4#2x.png", #"pin5#2x.png", #"pin6#2x.png",#"pin8#2x.png",#"pin9#2x.png",nil];
[self setupPinDictionary];
myAnnotation.image=[UIImage imageNamed:[imageNameArray objectAtIndex:indexPin]];
}
return myAnnotation;
}
I am inserting some annotations that are coming from a json server, but I wanted to check if the annotation is already on the map, if so, does not add it again. For they are being added on each other , have someone help me solve this problem?
my code:
// adiciona produtos ao mapa
- (void)adicionaAnnotationsNoMapa:(id)objetos{
NSMutableArray *annotationsPins = [[NSMutableArray alloc] init];
for (NSDictionary *annotationDeProdutos in objetos) {
CLLocationCoordinate2D location;
AnnotationMap *myAnn;
myAnn = [[AnnotationMap alloc] init];
location.latitude = [[annotationDeProdutos objectForKey:#"latitude"] floatValue];
location.longitude = [[annotationDeProdutos objectForKey:#"longitude"] floatValue];
myAnn.coordinate = location;
myAnn.title = [annotationDeProdutos objectForKey:#"name"];
myAnn.subtitle = [NSString stringWithFormat:#"R$ %#",[annotationDeProdutos objectForKey:#"price"]];
myAnn.categoria = [NSString stringWithFormat:#"%#", [annotationDeProdutos objectForKey:#"id_categoria"]];
myAnn.idProduto = [NSString stringWithFormat:#"%#", [annotationDeProdutos objectForKey:#"id"]];
[annotationsPins addObject:myAnn];
}
[self.mapView addAnnotations:annotationsPins];
}
You can iterate through annotations already on MkMapView and see if they are already there:
NSArray * annotations = [self.mapView.annotations copy];
for (NSDictionary *annotationDeProdutos in objetos)
{
// Check if annotation in annotations are duplicate of annotationDeProdutos.
// You can match using name.
}
Or the other way if you only want to show annotations from single server call:
[self.mapView removeAnnotations: self.mapView.annotations];
// Now add from JSON response.
You can do this for each of your annotations:
if(![self.mapView.annotations containsObject: myAnn]) {
[self.mapView addAnnotations: myAnn];
}
I solved the problem with this code :
// adiciona produtos ao mapa
- (void)adicionaAnnotationsNoMapa:(id)objetos{
NSMutableArray *annotationsPins = [[NSMutableArray alloc] init];
for (NSDictionary *annotationDeProdutos in objetos) {
CLLocationCoordinate2D location;
AnnotationMap *myAnn;
myAnn = [[AnnotationMap alloc] init];
location.latitude = [[annotationDeProdutos objectForKey:#"latitude"] floatValue];
location.longitude = [[annotationDeProdutos objectForKey:#"longitude"] floatValue];
myAnn.coordinate = location;
myAnn.title = [annotationDeProdutos objectForKey:#"name"];
myAnn.subtitle = [NSString stringWithFormat:#"R$ %#",[annotationDeProdutos objectForKey:#"price"]];
myAnn.categoria = [NSString stringWithFormat:#"%#", [annotationDeProdutos objectForKey:#"id_categoria"]];
myAnn.idProduto = [NSString stringWithFormat:#"%#", [annotationDeProdutos objectForKey:#"id"]];
if (self.mapView.annotations.count <1) {
[annotationsPins addObject:myAnn];
} else {
__block NSInteger foundIndex = NSNotFound;
[annotationsPins enumerateObjectsUsingBlock:^(AnnotationMap *annotation, NSUInteger idx, BOOL *stop) {
CLLocation *loc1 = [[CLLocation alloc] initWithLatitude:location.latitude longitude:location.longitude];
CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:annotation.coordinate.latitude longitude:annotation.coordinate.longitude];
if ([loc1 distanceFromLocation:loc2] <= 1.0f) {
foundIndex = idx;
*stop = YES;
}
}];
if (foundIndex != NSNotFound) {
[annotationsPins addObject:myAnn];
}
}
}
[self.mapView addAnnotations:annotationsPins];
}
I am having trouble showing pins on a map loading coordinates, title and subtitle from parse.com.
Here is my code. Is there any logical wrong? I get only the third row in the db showing, instead of all five that I have at the parse.com.
for(int i = 0; i<objects.count; i++)
{
int raknare = 1;
raknare++;
PFObject *tempObject = [kundUppgifter objectAtIndex:raknare];
PFGeoPoint *geoPoint = [tempObject objectForKey:#"CLAT"];
PFGeoPoint *geoPoint2 = (PFGeoPoint *)geoPoint;
NSString *cname = #"CNAME";
NSString *ctown = #"CTOWN";
kundUppgifter = [[NSArray alloc] initWithArray:objects];
objects = [NSArray arrayWithObjects:cname,ctown,geoPoint,nil];
NSMutableArray * locations = [[NSMutableArray alloc]init];
Annotation * myAnn;
myAnn = [[Annotation alloc]init];
CLLocationCoordinate2D location;
double longitude;
double latitude;
latitude = geoPoint2.latitude;
longitude = geoPoint2.longitude;
location.latitude = latitude;
location.longitude = longitude;
geoPoint.latitude = latitude;
geoPoint.longitude = longitude;
myAnn.coordinate = location;
myAnn.title = [tempObject objectForKey:#"CNAME"];
myAnn.subtitle = [tempObject objectForKey:#"CTOWN"];
[locations addObject:myAnn];
[self.myMapView addAnnotations:locations];
NSLog(#"geopoint is a pfobject with latitude %f, and longitude %f kundnamn %#,stad %#,", latitude, longitude, cname, ctown);
NSLog(#"%#", cname);
NSLog(#"%#", objects);
}
}
}];
Happy if you can help!
for(int i = 0; i<objects.count; i++)
{
int raknare = 1;
raknare++;
PFObject *tempObject = [kundUppgifter objectAtIndex:raknare];
}
This code inside of your loop will make raknare == 2 every iteration of the loop. You want to use the i variable you set to pull from -objectAtIndex: like this
for(int i = 0; i<objects.count; i++)
{
// This gives you a different object each iteration of the loop
PFObject *tempObject = [kundUppgifter objectAtIndex:i];
}
I am getting a GMSPolyline to custom location but I am not getting a route direction (GMSPolyline) from user location to some custom location.
What I have done is placed a GMSMapView and kept core location. I am updating the route in core location delegate method (locationManager: didUpdateLocations:).
I want to use Google Maps for iOS SDK since Apple Maps don't have directions in the country I need. My code is below:
- (void)viewDidLoad
{
[super viewDidLoad];
waypointStrings_ = [[NSMutableArray alloc]init];
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:self.latitude longitude:self.longitude zoom:13];
mapView_ = [GMSMapView mapWithFrame:CGRectZero camera:camera];
mapView_.myLocationEnabled = YES;
self.view = mapView_;
CLLocationManager *locManager = [[CLLocationManager alloc] init];
if ( [CLLocationManager locationServicesEnabled] ) {
[locManager setDelegate:self];
[locManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locManager startUpdatingLocation];
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocationCoordinate2D userCoordinate = [[locations lastObject] coordinate];
GMSMarker *marker = [GMSMarker markerWithPosition:CLLocationCoordinate2DMake(self.latitude,self.longitude)];
marker.map = mapView_;
NSString *majlisPositionString = [[NSString alloc] initWithFormat:#"%f,%f", self.latitude,self.longitude];
[waypointStrings_ addObject:majlisPositionString];
GMSMarker *userMarker = [GMSMarker markerWithPosition:CLLocationCoordinate2DMake(userCoordinate.latitude, userCoordinate.longitude)];
userMarker.map = mapView_;
NSString *userPositionString = [[NSString alloc] initWithFormat:#"%f,%f", userCoordinate.latitude, userCoordinate.longitude];
[waypointStrings_ addObject:userPositionString];
NSString *sensor = #"false";
NSArray *parameters = [NSArray arrayWithObjects:sensor, waypointStrings_, nil];
NSArray *keys = [NSArray arrayWithObjects:#"sensor", #"waypoints", nil];
NSDictionary *query = [NSDictionary dictionaryWithObjects:parameters forKeys:keys];
MDDirectionService *mds=[[MDDirectionService alloc] init];
SEL selector = #selector(addDirections:);
[mds setDirectionsQuery:query withSelector:selector withDelegate:self];
}
- (void)addDirections:(NSDictionary *)json {
NSDictionary *routes = [json objectForKey:#"routes"][0];
NSDictionary *route = [routes objectForKey:#"overview_polyline"];
NSString *overview_route = [route objectForKey:#"points"];
GMSPath *path = [GMSPath pathFromEncodedPath:overview_route];
GMSPolyline *polyline = [GMSPolyline polylineWithPath:path];
polyline.map = mapView_;
}
-(void)LoadMapRoute:(NSString*)SourceAddress andDestinationAddress:(NSString*)DestinationAdds
{
NSString *strUrl;
strUrl= [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/directions/json?origin=%#&destination=%#&sensor=false",SourceAddress,DestinationAdds];
strUrl=[strUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSData *data =[NSData dataWithContentsOfURL:[NSURL URLWithString:strUrl]];
NSError* error;
if (data) {
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:data //1
options:kNilOptions
error:&error];
NSArray *arrRouts=[json objectForKey:#"routes"];
if ([arrRouts isKindOfClass:[NSArray class]]&&arrRouts.count==0) {
[self zoomToFitMapAnnotations:self.mapView];
return;
}
CLLocationCoordinate2D coordinates[2];
coordinates[0].latitude = [[CommonUtils checkNullString:[AppDelegate getAppDelegate].strLatitude] doubleValue];Current loaction latitude.
coordinates[0].longitude = [[CommonUtils checkNullString:[AppDelegate getAppDelegate].strLongitude] doubleValue];//Current loaction longitude.
coordinates[1].latitude = [[CommonUtils checkNullString:latitute] doubleValue];
coordinates[1].longitude = [[CommonUtils checkNullString:longitude] doubleValue];
if (CLLocationCoordinate2DIsValid(coordinates[1]) && CLLocationCoordinate2DIsValid(coordinates[0]))
{
//NSLog(#"Coordinate valid");
self.mapView.delegate=self;
CLLocation *location1 = [[CLLocation alloc] initWithLatitude:coordinates[0].latitude longitude:coordinates[0].longitude];
CLLocation *location2 = [[CLLocation alloc] initWithLatitude:coordinates[1].latitude longitude:coordinates[1].longitude];
CLLocationDistance kilometers = [location1 distanceFromLocation:location2] / 1000;
//NSLog(#"%f",kilometers);
self.lblRideViewkilometer.text=[NSString stringWithFormat:#"%f KM",kilometers];
// //NSLog(#"Distance i meters: %f", [location1 distanceFromLocation:location2]);
// self.polyline = [MKPolyline polylineWithCoordinates:coordinates count:2];
// [self.mapView setVisibleMapRect:[self.polyline boundingMapRect]];
//
//
// //If you want the route to be visible
// [self.mapView addOverlay:self.polyline];
} else {
//NSLog(#"Coordinate invalid");
}
NSArray* arrpolyline = [[[json valueForKeyPath:#"routes.legs.steps.polyline.points"] objectAtIndex:0] objectAtIndex:0]; //2
double srcLat=[[[[json valueForKeyPath:#"routes.legs.start_location.lat"] objectAtIndex:0] objectAtIndex:0] doubleValue];
double srcLong=[[[[json valueForKeyPath:#"routes.legs.start_location.lng"] objectAtIndex:0] objectAtIndex:0] doubleValue];
double destLat=[[[[json valueForKeyPath:#"routes.legs.end_location.lat"] objectAtIndex:0] objectAtIndex:0] doubleValue];
double destLong=[[[[json valueForKeyPath:#"routes.legs.end_location.lng"] objectAtIndex:0] objectAtIndex:0] doubleValue];
CLLocationCoordinate2D sourceCordinate = CLLocationCoordinate2DMake(srcLat, srcLong);
CLLocationCoordinate2D destCordinate = CLLocationCoordinate2DMake(destLat, destLong);
[self addAnnotationSrcAndDestination:sourceCordinate :destCordinate andAdds:nil andDestinationAddress:DestinationAdds];
// NSArray *steps=[[aary objectAtIndex:0]valueForKey:#"steps"];
// replace lines with this may work
polyLinesArray =[[NSMutableArray alloc]initWithCapacity:0];
for (int i = 0; i < [arrpolyline count]; i++)
{
NSString* encodedPoints = [arrpolyline objectAtIndex:i] ;
MKPolyline *route = [self polylineWithEncodedString:encodedPoints];
[polyLinesArray addObject:route];
}
self.polyline = [MKPolyline polylineWithCoordinates:coordinates count:2];
[self.mapView setVisibleMapRect:[self.polyline boundingMapRect]];
[self.mapView addOverlays:polyLinesArray];
self.mapView.delegate = self;
[self zoomToFitMapAnnotations:self.mapView];
}else{
// [self.btnDirection setEnabled:NO];
// [self ShowAlert:#"didn't find direction"];
}
}-(void)addAnnotationSrcAndDestination :(CLLocationCoordinate2D )srcCord :(CLLocationCoordinate2D)destCord andAdds:(NSString*)SourceAddress andDestinationAddress:(NSString*)DestinationAdds
{
MKPointAnnotation *sourceAnnotation = [[MKPointAnnotation alloc]init];
destAnnotation = [[MKPointAnnotation alloc]init];
sourceAnnotation.coordinate=srcCord;
destAnnotation.coordinate=destCord;
sourceAnnotation.title=SourceAddress;
CLLocation *LocationAtual = [[CLLocation alloc] initWithLatitude:destCord.latitude longitude:destCord.longitude];
CLGeocoder *geocoder = [[CLGeocoder alloc] init] ;
[geocoder reverseGeocodeLocation:LocationAtual
completionHandler:^(NSArray *placemarks, NSError *error)
{
if (error){
//NSLog(#"Geocode failed with error: %#", error);
return;
}
CLPlacemark *placemark = [placemarks objectAtIndex:0];
//NSLog(#"placemark.ISOcountryCode %#",placemark.ISOcountryCode);
//NSLog(#"locality %#",placemark.subLocality);
//NSLog(#"postalCode %#",placemark.postalCode);
destAnnotation.title=[NSString stringWithFormat:#"%# %# ",placemark.name,placemark.locality];
// [self.mapView.userLocation setTitle:[NSString stringWithFormat:#"%# %# ",placemark.name,placemark.locality]];
}];
// destAnnotation.title=DestinationAdds;
//destAnnotation.title=[NSString stringWithFormat:#"%#,%#,%#",[self.dictRetailerInfo objectForKey:#"street_address1"],[self.dictRetailerInfo objectForKey:#"city"],[self.dictRetailerInfo objectForKey:#"country"]];
// destAnnotation.title=nil;
[self.mapView addAnnotation:sourceAnnotation];
[self.mapView addAnnotation:destAnnotation];
}
- (MKPolyline *)polylineWithEncodedString:(NSString *)encodedString {
const char *bytes = [encodedString UTF8String];
NSUInteger length = [encodedString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
NSUInteger idx = 0;
NSUInteger count = length / 4;
CLLocationCoordinate2D *coords = calloc(count, sizeof(CLLocationCoordinate2D));
NSUInteger coordIdx = 0;
float latitude = 0;
float longitude = 0;
while (idx < length) {
char byte = 0;
int res = 0;
char shift = 0;
do {
byte = bytes[idx++] - 63;
res |= (byte & 0x1F) << shift;
shift += 5;
} while (byte >= 0x20);
float deltaLat = ((res & 1) ? ~(res >> 1) : (res >> 1));
latitude += deltaLat;
shift = 0;
res = 0;
do {
byte = bytes[idx++] - 0x3F;
res |= (byte & 0x1F) << shift;
shift += 5;
} while (byte >= 0x20);
float deltaLon = ((res & 1) ? ~(res >> 1) : (res >> 1));
longitude += deltaLon;
float finalLat = latitude * 1E-5;
float finalLon = longitude * 1E-5;
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(finalLat, finalLon);
coords[coordIdx++] = coord;
if (coordIdx == count) {
NSUInteger newCount = count + 10;
coords = realloc(coords, newCount * sizeof(CLLocationCoordinate2D));
count = newCount;
}
}
MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordIdx];
free(coords);
return polyline;
}
-(void)zoomToFitMapAnnotations:(MKMapView*)aMapView
{
if([aMapView.annotations count] == 0)
return;
CLLocationCoordinate2D topLeftCoord;
topLeftCoord.latitude = -90;
topLeftCoord.longitude = 180;
CLLocationCoordinate2D bottomRightCoord;
bottomRightCoord.latitude = 90;
bottomRightCoord.longitude = -180;
for(MKPointAnnotation *annotation in self.mapView.annotations)
{
if (![[annotation class] isEqual:[MKUserLocation class]]) {
topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude);
topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude);
bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude);
bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude);
}
}
MKCoordinateRegion region;
region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5;
region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5;
region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.1; // Add a little extra space on the sides
region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.1; // Add a little extra space on the sides
region = [aMapView regionThatFits:region];
[self.mapView setRegion:region animated:YES];
mapZoom=YES;
}
//- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views
//{
// MKMapRect zoomRect = MKMapRectNull;
// for (id <MKAnnotation> annotation in mv.annotations)
// {
// MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
// MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);
// zoomRect = MKMapRectUnion(zoomRect, pointRect);
// }
// [mv setVisibleMapRect:zoomRect animated:YES];
//}
- (void)moveMapToLocation:(CLLocation*)tmpLocation {
CLLocationDistance visibleDistance = 1000; // 1 kilometers
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(tmpLocation.coordinate, visibleDistance, visibleDistance);
MKCoordinateRegion adjustedRegion = [self.mapView regionThatFits:viewRegion];
[self.mapView setRegion:adjustedRegion animated:YES];
}
var arrayPolyline = [GMSPolyline]()
var selectedRought:String!
func LoadMapRoute1()
{
let strUrl:String = "https://maps.googleapis.com/maps/api/directions/json?sensor=false&mode=driving&alternatives=true&origin=\(self.source.latitude),\(self.source.longitude)&destination=\(self.destination.latitude),\(self.destination.longitude)"
let escapedString = strUrl.replacingOccurrences(of: " ", with: "")
let url = URL(string: escapedString)
URLSession.shared.dataTask(with: url!, completionHandler:
{
(data, response, error) in
if(error != nil)
{
print("error")
}
else
{
do{
let json = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) as! [String : AnyObject]
let arrRouts = json["routes"] as! NSArray
for polyline in self.arrayPolyline
{
polyline.map = nil;
}
self.arrayPolyline.removeAll()
let pathForRought:GMSMutablePath = GMSMutablePath()
if (arrRouts.count == 0)
{
let distance:CLLocationDistance = CLLocation.init(latitude: self.source.latitude, longitude: self.source.longitude).distance(from: CLLocation.init(latitude: self.destination.latitude, longitude: self.destination.longitude))
pathForRought.add(self.source)
pathForRought.add(self.destination)
let polyline = GMSPolyline.init(path: pathForRought)
polyline.strokeWidth = 5
polyline.strokeColor = UIColor.blue
polyline.isTappable = true
self.arrayPolyline.append(polyline)
if (distance > 8000000)
{
polyline.geodesic = false
}
else
{
polyline.geodesic = true
}
polyline.map = self.mapView;
}
else
{
for (index, element) in arrRouts.enumerated()
{
let dicData:NSDictionary = element as! NSDictionary
let routeOverviewPolyline = dicData["overview_polyline"] as! NSDictionary
let path = GMSPath.init(fromEncodedPath: routeOverviewPolyline["points"] as! String)
let polyline = GMSPolyline.init(path: path)
polyline.isTappable = true
self.arrayPolyline.append(polyline)
polyline.strokeWidth = 5
if index == 0
{
polyline.strokeColor = UIColor.blue;
}
else
{
polyline.strokeColor = UIColor.darkGray;
}
polyline.geodesic = true;
}
for po in self.arrayPolyline.reversed()
{
po.map = self.mapView;
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5)
{
let bounds:GMSCoordinateBounds = GMSCoordinateBounds.init(path: GMSPath.init(fromEncodedPath: self.selectedRought)!)
self.mapView.animate(with: GMSCameraUpdate.fit(bounds))
}
}
catch let error as NSError
{
print("error:\(error)")
}
}
}).resume()
}
How to draw an arrow between two points on the map?
I try calc latitude and longitude, but something goes wrong.
Best regards, Max
This is my code and result picture
int currpoints1 = 2;
NSLog(#"!!!!!!!!%d ",numPoints);
while(currpoints1 < numPoints)
{
TrackPoint* current = nil;
CLLocationCoordinate2D* coordsArrrow = malloc((3) * sizeof(CLLocationCoordinate2D));
for (int i =currpoints1, j=0; i < numPoints; i=i+1, j++)
{
current = [cashpoints objectAtIndex:i];
coordsArrrow[j] = current.coordinate;
if (i % 2 !=0) {
int Gug = 30;
int ug;
float bx, by, ex, ey;
bx = coordsArrrow[0].latitude;by = coordsArrrow[0].longitude;
ex = coordsArrrow[1].latitude;ey = coordsArrrow[1].longitude;
float Lstr = sqrt((ex-ey)*(ex-ey)+(bx-by)*(bx-by));
ug = [self RetGradW:(abs(coordsArrrow[1].latitude-coordsArrrow[0].latitude)) height:abs(coordsArrrow[1].longitude-coordsArrrow[0].longitude)];
ug = ug - Gug;
coordsArrrow[0].latitude = ex;
coordsArrrow[0].longitude = ey;
coordsArrrow[1].latitude = ex+Lstr*cos(ug*M_PI/180);
coordsArrrow[1].longitude = ey+Lstr*sin(ug*M_PI/180);
ug=ug+2*Gug;
coordsArrrow[2].latitude = ex+Lstr*cos(ug*M_PI/180);
coordsArrrow[2].longitude = ey+Lstr*sin(ug*M_PI/180);
MKPolyline *points = [MKPolyline polylineWithCoordinates:coordsArrrow count:3];
points.subtitle = #"arrow";
[map addOverlay:points];
break;
}
}
free(coordsArrrow);
currpoints1 = currpoints1 +14;
}
Oh guys. I change other way. Make annotation and rotate with direction between two point.
metods :
calc direction:
int currpoints1 = 2;
NSLog(#"!!!!!!!!%d ",numPoints);
while(currpoints1 < numPoints)
{
TrackPoint* current = nil;
CLLocationCoordinate2D* coordsArrrow = malloc((2) * sizeof(CLLocationCoordinate2D));
for (int i =currpoints1, j=0; i < numPoints; i=i+1, j++)
{
current = [cashpoints objectAtIndex:i];
coordsArrrow[j] = current.coordinate;
if (i % 2 !=0) {
DirectAnnotation *placemark=[[DirectAnnotation alloc] initWithCoordinate: coordsArrrow[0]];
CLLocationCoordinate2D coord1 = coordsArrrow[0];
CLLocationCoordinate2D coord2 = coordsArrrow[1];
CLLocationDegrees deltaLong = coord2.longitude - coord1.longitude;
CLLocationDegrees yComponent = sin(deltaLong) * cos(coord2.latitude);
CLLocationDegrees xComponent = (cos(coord1.latitude) * sin(coord2.latitude)) - (sin(coord1.latitude) * cos(coord2.latitude) * cos(deltaLong));
CLLocationDegrees radians = atan2(yComponent, xComponent);
CLLocationDegrees degrees = radiansToDegrees(radians) + 360;
self.dir = fmod(degrees, 360);
NSLog(#"%f,%f %f,%f",coordsArrrow[0].latitude,coordsArrrow[0].longitude,coordsArrrow[1].latitude,coordsArrrow[1].longitude);
[self.map addAnnotation:placemark];
break;
}
}
free(coordsArrrow);
currpoints1 = currpoints1 +14;
}
and
annotation:
- (MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation{
if ([annotation isKindOfClass:[DirectAnnotation class]]) {
arrow=[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"parkingloc"];
arrow.image = [UIImage imageNamed:#"userLocationCompass.png"];
CGAffineTransform transform = CGAffineTransformMakeRotation(degreesToRadians(dir));
arrow.transform = transform;
return arrow;
}else {
return nil;
}}
But i have some problem
before zoom:
after zoom :
direction is confused.
Your arrows change the angle because you don't reuse them in viewForAnnotation correctly.
Just make some unique id for each arrow like this in viewForAnnotation:
routeAnnotationView = (MKAnnotationView *)[lmapView dequeueReusableAnnotationViewWithIdentifier:[NSString stringWithFormat:#"%f%f",annotation.coordinate.latitude, annotation.coordinate.longitude]];
if (!routeAnnotationView)
{
routeAnnotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:[NSString stringWithFormat:#"%f%f",annotation.coordinate.latitude, annotation.coordinate.longitude]];
UIImage *image = [self rotateImage:[UIImage imageNamed:#"arrpix11.png"] onDegrees:RADIANS_TO_DEGREES(curAngle)+90];
routeAnnotationView.image = image;
}
else
{
routeAnnotationView.annotation = annotation;
}
routeAnnotationView.canShowCallout = NO;
Use this for draw path between two location in Map.
http://code.google.com/p/ashiphone/downloads/detail?name=MapWithRoutes.zip&can=2&q=