Trying to request Google Panorama for a coordinate along with a specified radius.
Is there any way to get maximum supported radius for a coordinate ?
Just not sure what radius I can put into requestPanoramaNearCoordinate,
because even if I put 10000 (meters) it does not return any panorama (blank grey screen) where there are in fact panoramas within 50meters.
The requestPanoramaNearCoordinate:
[panoSvc requestPanoramaNearCoordinate:self.coordinate radius:1000 callback:^(GMSPanorama *panorama, NSError *error) {
if (error) {
NSLog(#"StreetView is not available at latlong = %f,%f", self.coordinate.latitude, self.coordinate.longitude);
return;
}
else{
GMSMarker *marker = [GMSMarker markerWithPosition:self.coordinate];
marker.panoramaView = panoView_;
[panoView_ moveNearCoordinate:self.coordinate];
}
}];
So the panoramaView should be moved to panorama.coordinate, not to where the destination coordinate is (which is self.coordinate and where the marker is),
see the code following the comment below.
[panoSvc requestPanoramaNearCoordinate:self.coordinate radius:1000 callback:^(GMSPanorama *panorama, NSError *error) {
if (error) {
NSLog(#"StreetView is not available at latlong = %f,%f", self.coordinate.latitude, self.coordinate.longitude);
return;
}
else{
GMSMarker *marker = [GMSMarker markerWithPosition:self.coordinate];
marker.panoramaView = panoView_;
//------------------
//so I should move panoramaView to panorama coordinate, not to where the destination coordinate is (which is self.coordinate and where the marker is)
//------------------
[panoView_ moveNearCoordinate:panorama.coordinate];
}
}];
Related
I am new to iOS and have to show Google Map having two restaurant locations with different lat and long in Los Angeles area. I need to make sure if user clicks on map it will allow user to get directions to that specific restaurant. So if all locations are on one map, user would need to click on desired restaurant/pin on map and get directions - correct?
try this I found it before
In -(void)mapView:(GMSMapView *)mapView didTapInfoWindowOfMarker:(GMSMarker *)marker// This method will get call after taping marker pin(GMSMapView map view delegate method).
{ get the latitude and longitude of that marker.
}
Take the latitude and longitude of current location
Now Draw route between two location
//Download LRouteController from this link https://github.com/lukagabric/LRouteController
//This will draw link between two co-ordinate
//In .h File declare LRouteController *_routeController;
if ([_coordinates count] > 1)
{
//Draw line between two co-ordinate
[_routeController getPolylineWithLocations:_coordinates travelMode:TravelModeDriving andCompletitionBlock:^(GMSPolyline *polyline, NSError *error) {
if (error)
{
NSLog(#"%#", error);
}
else if (!polyline)
{
NSLog(#"No route");
[_coordinates removeAllObjects];
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"No route" message:#"No route available for this route." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
else
{
//Drow route
_markerStart.position = [[_coordinates objectAtIndex:0] coordinate];
_markerStart.map = googleMapview;
_markerFinish.position = [[_coordinates lastObject] coordinate];
_markerFinish.map = googleMapview;
_polyline = polyline;
_polyline.strokeWidth = 3;
_polyline.strokeColor = [UIColor blueColor];
_polyline.map = googleMapview;
}
}];
}
//If you are unable to get taped pin latitude and longitude the you can use custom GMSMarker
Ex: #interface MapMarker : GMSMarker //Create new file of GMSMarker
#property (nonatomic, strong) coOrdinateData *data;(CoOrdinateData is NSObject class declare lat and long value)
#end
While adding marker on map use
MapMarker *marker= [[MapMarker alloc]init];
[marker setPosition:CLLocationCoordinate2DMake(LocationAtual.coordinate.latitude,LocationAtual.coordinate.longitude)];
marker.data=data;//Take lat and long value in object class and pass object class in marker object
After typing on map marker you can get value like
-(void)mapView:(GMSMapView *)mapView didTapInfoWindowOfMarker:(GMSMarker *)marker
{
NSString *strLat = ((MapMarker *)marker).data.lat ;
NSString *strLong = ((MapMarker *)marker).data.long ;
//Add both the current location and marker latitude and longitude in _coordinates and draw route.
}
I am working on a project which can fetch the list of nearby places (from my current place). I use Google Places API and what I have tried is shown below. I see new view which has a mapview with mark position of most prominent places and table which contains list of these places. I need to fetch list of the places so that I can render it on my tableview.
- (IBAction)pickPlace:(UIButton *)sender {
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(51.5108396, -0.0922251);
CLLocationCoordinate2D northEast = CLLocationCoordinate2DMake(center.latitude + 0.001, center.longitude + 0.001);
CLLocationCoordinate2D southWest = CLLocationCoordinate2DMake(center.latitude - 0.001, center.longitude - 0.001);
GMSCoordinateBounds *viewport = [[GMSCoordinateBounds alloc] initWithCoordinate:northEast coordinate:southWest];
GMSPlacePickerConfig *config = [[GMSPlacePickerConfig alloc] initWithViewport:viewport];
_placePicker = [[GMSPlacePicker alloc] initWithConfig:config];
[_placePicker pickPlaceWithCallback:^(GMSPlace *place, NSError *error) {
if (error != nil) {
NSLog(#"Pick Place error %#", [error localizedDescription]);
return;
}
if (place != nil) {
NSLog(#"Place name %#", place.name);
NSLog(#"Place address %#", place.formattedAddress);
NSLog(#"Place attributions %#", place.attributions.string);
} else {
NSLog(#"No place selected");
}
}];
}
Then you shouldn't use GMSPlacePicker, because it offers the UI to you for your user to make a single selection. If you want a list of places that you can display yourself then you should use the REST interface provided by google to get the required details and update your UI.
It is doable to get list of nearby places (from my current place) with Google Places API. I used the following method to achieve the same:
[GMSPlaceClient currentPlaceWithCallback:]
An array of nearby places with likelihood is returned.
I have a MKMapView and want to grab the cities name based on the center of the MKMapView. I do not want to drop any pins or annotations at all. Just automatically grab the data based on center of MKMapView location. I know there is this method '[placemarkName locality]'. But is there a way without using a placemark?
You could just do a reverseGeocodeLocation (effective iOS 5+) from the centerCoordinate of the map view. For example, I could do something like:
CLLocationCoordinate2D center = self.mapView.centerCoordinate;
CLGeocoder *coder = [[CLGeocoder alloc] init];
[coder reverseGeocodeLocation:[[CLLocation alloc] initWithLatitude:center.latitude longitude:center.longitude] completionHandler:^(NSArray *placemarks, NSError *error) {
self.cityLabel.text = [[placemarks firstObject] locality];
}];
This admittedly, returns an array of placemarks, but you don't have to do anything with them after you extract the city's name.
I'm using MapKit to display directions between locations, and I'm looking for a way to add an annotation that works similarly to the route annotation in the Apple Maps app, where annotations are showing each route's travel time (as shown in the image below). I am already drawing the directions correctly, the problem at hand is how to calculate a pair of coordinates along the route. That is, where to drop the annotation.
I thought about somehow using the MKDirection (which contains complete directions, step by step) but I am not sure how I would generate a pair of coordinates that are somewhere in the middle of the route.
I have not been able to find any kind of support for this in the MapKit documentation. Any ideas?
This is how I generate the route and display it.
- (void)generateRoute {
MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];
request.source = [MKMapItem mapItemForCurrentLocation];
request.destination = self.destinationMapItem;
MKDirections *directions = [[MKDirections alloc] initWithRequest:request];
[directions calculateDirectionsWithCompletionHandler:
^(MKDirectionsResponse *response, NSError *error) {
if (error) {
// Handle Error
} else {
[self showRoute:response];
}
}];
}
- (void)showRoute:(MKDirectionsResponse *)response {
[self.mapView removeOverlays:self.mapView.overlays];
for (MKRoute *route in response.routes)
{
[self.mapView addOverlay:route.polyline level:MKOverlayLevelAboveRoads];
}
[self fitRegionToRoute];
}
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id < MKOverlay >)overlay
{
MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
renderer.strokeColor = [UIColor blueColor];
renderer.alpha = 0.7;
renderer.lineWidth = 4.0;
return renderer;
}
Questioner's edit:
Finally made it work with the help of this answer. I added this to the code below, where it says Here do the magic:
MKMapPoint middlePoint = route.polyline.points[route.polyline.pointCount/2];
[self createAndAddAnnotationForCoordinate:MKCoordinateForMapPoint(middlePoint)];
Original answer:
I don't know whether this will work or not. Just my idea on your question.
I guess you would have created the routes as following
(Check my inline comments)
MKDirectionsRequest *request =
[[MKDirectionsRequest alloc] init];
request.source = [MKMapItem mapItemForCurrentLocation];
request.destination = _destination;
request.requestsAlternateRoutes = NO;
MKDirections *directions =
[[MKDirections alloc] initWithRequest:request];
[directions calculateDirectionsWithCompletionHandler:
^(MKDirectionsResponse *response, NSError *error) {
if (error) {
// Handle error
} else {
for (MKRoute *route in response.routes)
{
[_routeMap addOverlay:route.polyline level:MKOverlayLevelAboveRoads];
//Here do the magic
//MKPolyline confronts to MKOverlay so you can get the coordinate like
//route.polyline.coordinate once you get the coordinate then you can build
//a annotation. A annotation is nothing but a coordinate with some title.
//According to MKOverlay coordinate property it justs gives you the
//center point of the overlay area
[self createAndAddAnnotationForCoordinate:route.polyline.coordinate]
}
}
}];
Adding Annotation
-(void) createAndAddAnnotationForCoordinate : (CLLocationCoordinate2D) coordinate{
MyAnnotation* annotation= [[MyAnnotation alloc] init];
annotation.coordinate = coordinate;
annotation.title = #"Any Title";
annotation.subtitle = #"Any Subtitle";
[yourMap addAnnotation: annotation];
}
If you want to know the middle for swift you can use the following code :
MKCoordinateForMapPoint(route.polyline.points()[route.polyline.pointCount/2])
Exemple of use :
directions.calculateDirectionsWithCompletionHandler ({
(response: MKDirectionsResponse?, error: NSError?) in
if error == nil {
self.showRoute(response!)
}
else{
print("some error")
}
})
func showRoute(response:MKDirectionsResponse){
for route in response.routes {
self.map.addOverlay(route.polyline, level: MKOverlayLevel.AboveRoads)
self.map.setCenterCoordinate(route.polyline.coordinate, animated: true)
self.map.setRegion(MKCoordinateRegionMakeWithDistance(route.polyline.coordinate, route.distance*0.75, route.distance*0.75), animated: true)
let routeAnnotation = MKPointAnnotation()
routeAnnotation.coordinate = MKCoordinateForMapPoint(route.polyline.points()[route.polyline.pointCount/2])
map.addAnnotation(routeAnnotation)
}
}
Perhaps not the most efficient way, but should still likely be quick, would be to calculate the midpoint of your start and end points (i.e., average their lats and longs). Then, iterate through your polyline points checking the distance from each to that midpoint. Take the closest match.
Even if the line is wildly curved, the midpoint will be directly between the ends. Some point on the wild curve is the closest to that external midpoint and is likely a good place to put the annotation.
Once you have an MKRoute, the approximate centre-point can be found using:
route.polyline.coordinate
This returns a CLLocationCoordinate2D that you can use to centre your annotation.
Appreciate this is an old question but I'd been searching for something like this for a while and ended up calculating the centre manually. Turns out it's very straightforward since iOS 8.
I suggest you see this , Integrated with routing.
I'm using MapKit to display directions between locations, and I'm looking for a way to add an annotation that works similarly to the route annotation in the Apple Maps app, where annotations are showing each route's travel time (as shown in the image below). I am already drawing the directions correctly, the problem at hand is how to calculate a pair of coordinates along the route. That is, where to drop the annotation.
I thought about somehow using the MKDirection (which contains complete directions, step by step) but I am not sure how I would generate a pair of coordinates that are somewhere in the middle of the route.
I have not been able to find any kind of support for this in the MapKit documentation. Any ideas?
This is how I generate the route and display it.
- (void)generateRoute {
MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];
request.source = [MKMapItem mapItemForCurrentLocation];
request.destination = self.destinationMapItem;
MKDirections *directions = [[MKDirections alloc] initWithRequest:request];
[directions calculateDirectionsWithCompletionHandler:
^(MKDirectionsResponse *response, NSError *error) {
if (error) {
// Handle Error
} else {
[self showRoute:response];
}
}];
}
- (void)showRoute:(MKDirectionsResponse *)response {
[self.mapView removeOverlays:self.mapView.overlays];
for (MKRoute *route in response.routes)
{
[self.mapView addOverlay:route.polyline level:MKOverlayLevelAboveRoads];
}
[self fitRegionToRoute];
}
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id < MKOverlay >)overlay
{
MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
renderer.strokeColor = [UIColor blueColor];
renderer.alpha = 0.7;
renderer.lineWidth = 4.0;
return renderer;
}
Questioner's edit:
Finally made it work with the help of this answer. I added this to the code below, where it says Here do the magic:
MKMapPoint middlePoint = route.polyline.points[route.polyline.pointCount/2];
[self createAndAddAnnotationForCoordinate:MKCoordinateForMapPoint(middlePoint)];
Original answer:
I don't know whether this will work or not. Just my idea on your question.
I guess you would have created the routes as following
(Check my inline comments)
MKDirectionsRequest *request =
[[MKDirectionsRequest alloc] init];
request.source = [MKMapItem mapItemForCurrentLocation];
request.destination = _destination;
request.requestsAlternateRoutes = NO;
MKDirections *directions =
[[MKDirections alloc] initWithRequest:request];
[directions calculateDirectionsWithCompletionHandler:
^(MKDirectionsResponse *response, NSError *error) {
if (error) {
// Handle error
} else {
for (MKRoute *route in response.routes)
{
[_routeMap addOverlay:route.polyline level:MKOverlayLevelAboveRoads];
//Here do the magic
//MKPolyline confronts to MKOverlay so you can get the coordinate like
//route.polyline.coordinate once you get the coordinate then you can build
//a annotation. A annotation is nothing but a coordinate with some title.
//According to MKOverlay coordinate property it justs gives you the
//center point of the overlay area
[self createAndAddAnnotationForCoordinate:route.polyline.coordinate]
}
}
}];
Adding Annotation
-(void) createAndAddAnnotationForCoordinate : (CLLocationCoordinate2D) coordinate{
MyAnnotation* annotation= [[MyAnnotation alloc] init];
annotation.coordinate = coordinate;
annotation.title = #"Any Title";
annotation.subtitle = #"Any Subtitle";
[yourMap addAnnotation: annotation];
}
If you want to know the middle for swift you can use the following code :
MKCoordinateForMapPoint(route.polyline.points()[route.polyline.pointCount/2])
Exemple of use :
directions.calculateDirectionsWithCompletionHandler ({
(response: MKDirectionsResponse?, error: NSError?) in
if error == nil {
self.showRoute(response!)
}
else{
print("some error")
}
})
func showRoute(response:MKDirectionsResponse){
for route in response.routes {
self.map.addOverlay(route.polyline, level: MKOverlayLevel.AboveRoads)
self.map.setCenterCoordinate(route.polyline.coordinate, animated: true)
self.map.setRegion(MKCoordinateRegionMakeWithDistance(route.polyline.coordinate, route.distance*0.75, route.distance*0.75), animated: true)
let routeAnnotation = MKPointAnnotation()
routeAnnotation.coordinate = MKCoordinateForMapPoint(route.polyline.points()[route.polyline.pointCount/2])
map.addAnnotation(routeAnnotation)
}
}
Perhaps not the most efficient way, but should still likely be quick, would be to calculate the midpoint of your start and end points (i.e., average their lats and longs). Then, iterate through your polyline points checking the distance from each to that midpoint. Take the closest match.
Even if the line is wildly curved, the midpoint will be directly between the ends. Some point on the wild curve is the closest to that external midpoint and is likely a good place to put the annotation.
Once you have an MKRoute, the approximate centre-point can be found using:
route.polyline.coordinate
This returns a CLLocationCoordinate2D that you can use to centre your annotation.
Appreciate this is an old question but I'd been searching for something like this for a while and ended up calculating the centre manually. Turns out it's very straightforward since iOS 8.
I suggest you see this , Integrated with routing.