iOS - Build polyline from Google Maps Directions API response - ios

How can I get a polyline out of the Directions API JSON response?
Using the overview_polyline is not an option as it is only a smoothened version of the actual polyline.
I also tried getting the start and end location coordinates from the steps, however those will only give me a very inaccurate polyline, because they only contain a few coordiantes.
How can I get an accurate polyline out of the Directions response?
EDIT: Using #SaxonDruce answer, I can get accurate polylines however, they look like this:

Based on the sample response, you'll need something equivalent to:
response.routes[0].legs[0].steps[i].polyline.points
So, get the first route, then the first leg, then loop over the steps, then get the polyline, then get the points.

To add to saxon druce's answer, You can loop over all the steps of first leg and combine all the points to form a polyline.
List<LatLng> points = new ArrayList<>();
for (DirectionsStep step : legs[i].steps) {
points.addAll(step.polyline.decodePath());
}
EncodedPolyline legPolyline = new EncodedPolyline(points);

Related

Migrating to Places 4.0 SDK, how to migrate place Bias?

I am migrating to the new places SDK 4.0
The old func was:
findAutocompletePredictions(fromQuery: query,
bounds: bounds,
boundsMode: .bias,
filter: filter,
sessionToken: token) { (prediction, error) in
callback(prediction, error)
}
the new func as per docs is
findAutocompletePredictions(fromQuery: query,
filter: filter,
sessionToken: token) { (prediction, error) in
callback(prediction, error)
}
I see that bounds bias is now set on the GMSAutocompleteFilter filter
This has a locationBias property where i set some and it takes a parameter of <GMSPlaceLocationBias>
The issue i have is there is no info on what to provide here...GMSPlaceLocationBias is a protocol, and i have no idea what im meant to use object wise to provide the old bounds data.
Conforming to the protocol gives me a locationBiasURLQueryItem fun to populate, with no further documentation on what should go in this function
So im stuck and cant upgrade as there doesnt seem to be a clear way forward.
Anyone have any ideas? Docs are here: https://developers.google.com/places/ios-sdk/reference/interface_g_m_s_places_client#ab60773feec0e68751c5a7f1066b9d252)
My attempt to construct the filter is:
let filter = GMSAutocompleteFilter()
if case .location(let location) = _locationController.locationStatus {
filter.locationBias = .some(location)
}
But obviously my custom location model object doesnt confirm to GMSPlaceLocationBias and is a struct so cant be used and errors
I got totally lost on this as well, but just found an example buried in one of the guides here.
In short the implementation looks like this:
let filter = GMSAutocompleteFilter()
filter.locationBias = GMSPlaceRectangularLocationOption(bounds.northEast, bounds.southWest)
Here I'm using the same bounds I had previously been using in 3.x (in my case from the map currently being displayed) to get those northEast and southWest coordinates, but you can generate your own based on how where you are trying to bias results.
I wish they had just made ANY indication in their docs that this was the intended way to do it.

Avoid coordinates when generating a route using Mapbox Direction API

I have been using Mapbox for my app to generate route and turn-by-turn navigation and it's working well. However I would like to avoid to go through some coordinates of the route but I can't figure it out.
The code to get the route :
Directions.shared.calculate(options) { [unowned self] (waypoints, routes, error) in
// Take first route and customize it in a way to get around some coordinates
}
Here is a scenario :
1- User location is latitude = 37.332331410000002, longitude = -122.0312186
2- The user is going to Santa Clara Unified School located on latitude = 37.354100000000003,longitude = -121.9552
3- The Api generates the following route :
[0] = {
latitude = 37.332329999999999
longitude = -122.03118000000001
}
[1] = {
latitude = 37.332619999999999
longitude = -122.03118000000001
}
[2] = {
latitude = 37.332609999999995
longitude = -122.03097000000001
}
[3] = {
latitude = 37.332609999999995
longitude = -122.03076000000001
}
[4] = {
latitude = 37.332199999999993
longitude = -122.03076000000001
}
[5] = {
latitude = 37.331689999999995
longitude = -122.03076000000001
}
[6] = {
latitude = 37.331689999999995
longitude = -122.03190000000002
}
[7] = {
latitude = 37.331719999999997
longitude = -122.03199000000002
}
[8] = {
latitude = 37.331759999999996
longitude = -122.03205000000003
} ...
4- Suppose the generated route goes through East Homestead Rd, I would like to be able to avoid this road and generate a new route even if it's a longer one.In the screen below avoid the route in red because going through East Homestead Rd and take the next fastest route not going through East Homestead Rd
Any help would be appreciated !
EDIT : Here is the query for finding if a route has points to avoid in it
// $linestring is the array of coordinates from the route in the string format of (lng lat,lng2 lat2,lng3 lat3,lng4 lat4....)
$query = $this->em->createQuery('
SELECT count(i) as counter
FROM HitsBundle:Hit i
WHERE i.datetime BETWEEN :lastMonth AND :now
AND
MBRCovers(
ST_Buffer(
ST_GeomFromText(\'LineString('.$linestring.')\') ,
0.00001
),
i.coordinates
) = 1
GROUP BY i.coordinates
HAVING counter > 1
')
->setParameter('lastMonth', $lastMonth)
->setParameter('now', new \DateTime())
->setMaxResults(1);
EDIT: Related issue on Github
I may be rough-guessing here, but looking through Mapbox API it does not have any options to avoid while generating routes, therefore you need to implement some route-selection logic on client-side.
Basically you need to have an algorithm which gets a set of points to avoid and checks if your Route geometry GeoJSON or Polyline are within some threshold range from given points. If it is - discard the route (or lower route priority).
Of course it may fail to find a route if all routes provided by Mapbox are discarded - Mapbox does not know about your restrictions, therefore using weight for routes could be one option of solving this.
These posts might give you some hints:
Is it possible to determine if a GeoJSON point is inside a GeoJSON polygon using JavasScript
How to check if a Latitude/Longitude point is on the GRoute in Google Maps API
After few months dealing with the MapBox Direction API we've come to the conclusion that it's not reliable for this specific use case. When calculating routes from Point A to Point B using the Direction API, MapBox offers an option includesAlternativeRoutes if set to true it provides alternative routes. However this is not consistent and in most cases it returns only the preferred route.
According to MapBox :
If the value of this property is true, the server attempts to find additional reasonable routes that visit the waypoints. Regardless, multiple routes are only returned if it is possible to visit the waypoints by a different route without significantly increasing the distance or travel time.
So we will switch to Google Maps as this feature is crucial to our business logic.

How can I visualise tweets on a map in Processing?

I'm trying to use the twitter API to search for a keyword and get the location of that particular tweet to then visualise onto a map.
I've successfully created my map using unfolding maps and tilemill, I'm just struggling with the twitter part. Using the twitter 4J library, I've tried the following code but I'm not able to get the location as coordinates. Also, once I've got the coordinates I dont know how to go about visualising them on my map.
import twitter4j.*;
import twitter4j.api.*;
import twitter4j.auth.*;
import twitter4j.conf.*;
import twitter4j.json.*;
import twitter4j.management.*;
import twitter4j.util.*;
import twitter4j.util.function.*;
ConfigurationBuilder cb = new ConfigurationBuilder();
Twitter twitterInstance;
Query queryForTwitter;
void setup() {
cb.setOAuthConsumerKey("**********");
cb.setOAuthConsumerSecret("*******");
cb.setOAuthAccessToken("*********");
cb.setOAuthAccessTokenSecret("*********");
twitterInstance = new TwitterFactory( cb.build()).getInstance();
queryForTwitter = new Query("#nature");
size(640, 440);
background(0);
FetchAndDrawTweets();
}
void FetchAndDrawTweets() {
try {
QueryResult result = twitterInstance.search(queryForTwitter);
ArrayList tweets = (ArrayList) result.getTweets();
for (int i=0; i<tweets.size(); i++) {
Status t = (Status) tweets.get(i);
String user = (t.getUser()).getLocation();
text(user + ":" , 20,15+i*15);
}
}
catch(TwitterException te) {
println("Couldn't connect:" + te);
}
}here
I'm quite new to processing, so please be patient with me as I don't even know if I'm going about this the right way.
Any help would be gratefully appreciated!!
Nice work on separating your problem into smaller sub-problems. It's a good idea to separate the "get tweets and locations" step from the "show stuff on map" step. Good work.
As for getting the location of a tweet, there are two places you should look:
The Twitter4J JavaDocs: This is a list of every class, function, and variable available to you from the Twitter4J library. This should be your first stop. Do you see anything that looks useful in here? Specifically, the Status class has a getGeoLocation() function that looks pretty promising.
The Twitter API: this is the underlying JavaScript API that the Twitter4J library is built on. Check out this documentation for more details on what's going on underneath the Twitter4J library. Specifically, this page says the the geo object is deprecated and that you should use the coordinates field instead.
So the first thing I would try is the getGeoLocation() function. But note that not every tweet will have a location, since users can disable location tracking. Also note that if the underlying JavaScript library no longer provides the geo object, and if the Twitter4J library is using that to populate its getGeoLocation() function, then you won't be able to get at the location through Twitter4J. I haven't tested that at all though.

(delphi application) wrong location spotted

i have pairs of coorinates:
GpsLatitude GpsLongitude
32.012919 34.547592,
32.012798 34.54763,
32.012827 34.547584,
32.012814 34.547608,
32.01273 34.54765,
32.012868 34.547631,
32.012834 34.547577,
and i have show it on google map in delphi application.
i find an example here a delphi code example
and it works. But when i trying to use it with my coordinates it point
to wrong location, but when i open it in browser, like this
"32 01.2834,34 54.7577"
it work good, unfortunatly it does not work in delphi.
what can be wrong??
if you look the GotoLatLng javascript function used in the article,
function GotoLatLng(Lat, Lang) {
var latlng = new google.maps.LatLng(Lat,Lang);
map.setCenter(latlng);
var marker = new google.maps.Marker({
position: latlng,
map: map,
title:Lat+","+Lang
});
}
You can see a call to the google.maps.LatLng() function, and this needs to be given two numbers in decimal format. you are using a value like this 32 01.2919, 34 54.7592 which is in degrees and minutes format, so that format must be converted to decimal before be passed to the javascript function. Now the reason because that value works in the google maps page is because that page internally resolves the string passed as parameter and returns a colletion of markers as result.

How to receive updates to the Twitter social graph?

I just got some crazy ideas for analyzing the Twitter social graph (i.e., representing follow-relations as the edges of a graph). Interestingly, the Twitter API provides methods for creating the graph. It is possible to read out a static snapshot of the social graph, whereas Twitter is a very dynamic network. It would be great if one could dynamically update the graph. So my question is: Is there any way to get notified by Twitter when anyone starts or stops to follow anyone?
I believe that the documentation you linked to would definitely mention that.
I'm quite certain that you need to do your own follower-list checking, and compare results on a regular basis.
I do this if someone follows me or not and how many followers they have and i generate this chart
public function existsFriendship($username,$friend)
{
try
{
if ($this->twitter->existsFriendship($username, $friend))
return true;
}
catch(Exception $e)
{
$this->debug($e->getMessage());
}
}
for the chart generation i use pchart.
in smarty template the code looks like this;
include("pChart/pData.class");
include("pChart/pChart.class"); ![alt text][1]
// Initialise the graph
$Test = new pChart(700,230);
$Test->setFontProperties("Fonts/tahoma.ttf",13);
$Test->setGraphArea(40,30,680,200);
$Test->drawGraphArea(252,252,252,TRUE);
$Test->drawScale($DataSet->GetData(),$DataSet->GetDataDescription(),SCALE_NORMAL,150,150,150,TRUE,0,2);
$Test->drawGrid(4,TRUE,230,230,230,70);
// Draw the line graph
$Test->drawLineGraph($DataSet->GetData(),$DataSet->GetDataDescription());
$Test->drawPlotGraph($DataSet->GetData(),$DataSet->GetDataDescription(),3,2,255,255,255);
// Finish the graph
$Test->setFontProperties("Fonts/tahoma.ttf",12);
$Test->drawLegend(45,35,$DataSet->GetDataDescription(),255,255,255);
$Test->setFontProperties("Fonts/tahoma.ttf",12);
$Test->drawTitle(60,22,"Twitter Graph",50,50,50,585);
$example = $Test->Render("templates/example1.png");
$smarty->assign("example",$example);
$smarty->display('index.tpl');
finaly the result
alt text http://img691.imageshack.us/img691/6749/example1k.png

Resources