GoogleMap API Gives Wrong Coordinates for Direction between two Points
Below answer is for smooth path between two location with help of @A Báo:
-(void)viewDidLoad {
// Create a GMSCameraPosition that tells the map to display the
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:21.718472 longitude:73.030422 zoom:6];
mapView_ = [GMSMapView mapWithFrame:CGRectZero camera:camera];
mapView_.delegate=self;
mapView_.myLocationEnabled = YES;
mapView_.settings.myLocationButton=YES;
mapView_.settings.indoorPicker=NO;
mapView_.settings.compassButton=YES;
self.view = mapView_;
NSString *str=@"http://maps.googleapis.com/maps/api/directions/json?origin=Bharuch,gujarat&destination=vadodara,gujarat&sensor=false";
NSURL *url=[[NSURL alloc]initWithString:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSArray* latestRoutes = [json objectForKey:@"routes"];
NSString *points=[[[latestRoutes objectAtIndex:0] objectForKey:@"overview_polyline"] objectForKey:@"points"];
@try {
// TODO: better parsing. Regular expression?
NSArray *temp= [self decodePolyLine:[points mutableCopy]];
GMSMutablePath *path = [GMSMutablePath path];
for(int idx = 0; idx < [temp count]; idx++)
{
CLLocation *location=[temp objectAtIndex:idx];
[path addCoordinate:location.coordinate];
}
// create the polyline based on the array of points.
GMSPolyline *rectangle = [GMSPolyline polylineWithPath:path];
rectangle.strokeWidth=5.0;
rectangle.map = mapView_;
}
@catch (NSException * e) {
// TODO: show error
}
}
-(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;
}
Screenshot of this code you can compare it with previous screenshot which i used in asking Question:
Show direction between two points in Google Map Api with a padding
Since I saw already a few questions on SO about offsetting stuff that would appear behind elements overlaid on the map, I thought I'd give it a bit of time.
Here is how I did it:
Plot a route on the map and listen for the map
idle
event before starting with the offset process.Check the leftmost point of the route bounds to see if it falls behind the overlay. This makes use of the
fromLatLngToPoint()
method to translate from lat/lng coordinates to a point on the map projection.Check how much you can offset the route by comparing the leftmost and rightmost points of the route with the available space on the map. Offset the map until both points fit on the map canvas.
If both points cannot fit within the map canvas, zoom out and start the same process again.
The script must be aware of the width of the overlay and you should apply some margins so that it always fits well.
Here is the function used to translate between coordinates and point:
function fromLatLngToPoint(latLng) {
var scale = Math.pow(2, map.getZoom());
var nw = new google.maps.LatLng(map.getBounds().getNorthEast().lat(), map.getBounds().getSouthWest().lng());
var worldCoordinateNW = map.getProjection().fromLatLngToPoint(nw);
var worldCoordinate = map.getProjection().fromLatLngToPoint(latLng);
return new google.maps.Point(Math.floor((worldCoordinate.x - worldCoordinateNW.x) * scale), Math.floor((worldCoordinate.y - worldCoordinateNW.y) * scale));
}
Here is the demo:
JSFiddle demo
I am sure it can still be optimized but it does the job quite well. Please report issues here if you find any.
Edit:
The same technique works with markers too:
JSFiddle demo
google maps - wrong (different) routes directions
Those are two different things. The correct route is passing in google.map.LatLng objects, the incorrect route is not. To use geographic coordinates you need to pass in google.map.LatLng objects, otherwise the coordinates get geocoded.
destination LatLng|string Location of destination. This can be specified as either a string to be geocoded or a LatLng. Required.
origin LatLng|string Location of origin. This can be specified as either a string to be geocoded or a LatLng. Required.
See this question for how to convert a comma separated string to a google.maps.LatLng object.
Google Maps Directions API showing wrong directions
Fixed the Problem. There was an alternative place with the same name as one of my way-points. I changed the way-point in my URL from a name to specific Lat-Long Coordinates and that solved the problem for me.
Google Maps Directions API Calculating Incorrect Route
When I change complete_trip():
to
@app.route("/finalize_new_trip", methods=["GET"])
def complete_trip():
return render_template("finish_new_trip.html", trip_name ='new trip', origin='new york, ny', destination='los angeles, california', waypoints='topeka, kansas')
and request the page, the results are perfect (a trip from NY to LA that goes through Topeka). You've got a lot of commented out code everywhere. I have a feeling that somewhere you're not getting the data you expect (for example, we can't see the form HTML used to post this data).
distance matrix google maps gives wrong distance between two locations while using in curl php code
What I get from the distance matrix is (modifying this example):
origin[0]:51.509904,-0.134135
origin[0]:A4, London W1J, UK to destination[0]:51.509904,-0.134135: 1 m in 1 min
origin[0]:A4, London W1J, UK to destination[1]:51.517618,-0.096778: 4.1 km in 15 mins
origin[0]:A4, London W1J, UK to destination[2]:51.501786,-0.053648: 7.4 km in 23 mins
origin[0]:A4, London W1J, UK to destination[3]:51.495042,-0.131382: 2.8 km in 9 mins
origin[0]:A4, London W1J, UK to destination[4]:21.118692,73.117554: 11,411 km in 7 days 5 hours
fiddle
The distance is returned in the results (at least in the Google Maps Javascript API v3, should be in the web service as well): results[j].distance.text
code snippet:
var geocoder;var map;var bounds = new google.maps.LatLngBounds();var markersArray = [];var destinationIcon = 'https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=D|FF0000|000000';var originIcon = 'https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=O|FFFF00|000000';var locations;
function initialize() { map = new google.maps.Map( document.getElementById("map_canvas"), { center: new google.maps.LatLng(37.4419, -122.1419), zoom: 13, mapTypeId: google.maps.MapTypeId.ROADMAP });
geocoder = new google.maps.Geocoder();
$userLat1 = 51.509904342252; $userLong1 = -0.13413459062576; $userLat2 = 51.517618; $userLong2 = -0.096778; $userLat3 = 51.5017863; $userLong4 = -0.0536478;
// $userLat = 51.509904342252; // $userLong = -0.13413459062576; $lat2 = 51.495042; $long2 = -0.131382; $userExtralat2 = 21.118692, $userExtralong2 = 73.117554
locations = [new google.maps.LatLng($userLat1, $userLong1), new google.maps.LatLng($userLat2, $userLong2), new google.maps.LatLng($userLat3, $userLong4), // new google.maps.LatLng($userLat, $userLong), new google.maps.LatLng($lat2, $long2), new google.maps.LatLng($userExtralat2, $userExtralong2) ];}
function calculateDistances() { var service = new google.maps.DistanceMatrixService(); service.getDistanceMatrix({ origins: locations, destinations: locations, travelMode: google.maps.TravelMode.DRIVING, unitSystem: google.maps.UnitSystem.METRIC, avoidHighways: false, avoidTolls: false }, callback);}
function callback(response, status) { if (status != google.maps.DistanceMatrixStatus.OK) { alert('Error was: ' + status); } else { var origins = response.originAddresses; var destinations = response.destinationAddresses; var outputDiv = document.getElementById('outputDiv'); outputDiv.innerHTML = ''; deleteOverlays(); outputDiv.innerHTML += "origin[0]:" + locations[0].toUrlValue(6) + '<br>'; for (var i = 0; i < origins.length; i++) { var results = response.rows[i].elements; addMarker(origins[i], false); for (var j = 0; j < results.length; j++) { // addMarker(destinations[j], true); outputDiv.innerHTML += "origin[" + i + "]:" + origins[i] + ' to destination[' + j + ']:' + locations[j].toUrlValue(6) /* destinations[j] */ + ': ' + results[j].distance.text + ' in ' + results[j].duration.text + '<br>'; } } }}
function addMarker(location, isDestination) { var icon; if (isDestination) { icon = destinationIcon; } else { icon = originIcon; } geocoder.geocode({ 'address': location }, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { bounds.extend(results[0].geometry.location); map.fitBounds(bounds); var marker = new google.maps.Marker({ map: map, position: results[0].geometry.location, icon: icon }); markersArray.push(marker); } else { alert('Geocode was not successful for the following reason: ' + status); } });}
function deleteOverlays() { for (var i = 0; i < markersArray.length; i++) { markersArray[i].setMap(null); } markersArray = [];}
google.maps.event.addDomListener(window, "load", initialize);
html,body,#map_canvas { height: 500px; width: 500px; margin: 0px; padding: 0px}#content-pane { width: 100%; padding-left: 2%;}#outputDiv { font-size: 11px;}
<script src="https://maps.googleapis.com/maps/api/js"></script><div id="map_canvas" style="border: 2px solid #3872ac;"></div><div id="content-pane"> <div id="inputs"> <p> <button type="button" onclick="calculateDistances();">Calculate distances </button> </p> </div> <div id="outputDiv"></div></div>
Related Topics
Uitableview Automatic Dimension Not Working Correctly
How to Queue Multiple Accessibility Notifications for Voiceover
How to Call Objective-C Instancetype Method in Swift
Random Glitchy Rendering of Svg on iOS/Wkwebview
Uiactivityviewcontroller Subject Not Working for Outlook
Why Use Corebluetooth Connectperipheral Did Not Call Delegate Methods in iOS8
Restkit 0.20 JSON Mapping Along with Additional Offline Data
Adaptive Launch Screen Storyboards: How to Differentiate iPad Orientations
iOS Wkwebview Swift JavaScript Enable
Testflight Sdk and iOS Simulator - How to Use
How to Use Pod in Notification Service Extension
Sync Video in Avplayerlayer and Avplayerviewcontroller
Detect Permission of Media Library iOS
Apns Http2 API Not Returning Status 410 After Uninstalling App