Angularjs geo-location with existing data - geolocation

I am using angularjs in my application, its great working with angularjs. I have one problem inside angularjs geo-location with existing data. Consider code:
$scope.lat = 18.50;
$scope.long = 73.70;
$scope.places = [{placename: 'CCD',lat: 18.56,long: 73.50},{placename: 'HDFC bank',lat: 18.58,long: 73.40},{placename: 'Play ground',lat: 18.50,long: 73.72},{placename: 'Kids School',lat: 18.45,long: 73.78}];
I have latitude and longitude of one place and want to get places nearby 20km(providing radius) within $scope.places. So how can i get that.Any suggestion. Thanks.

Related

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 to perform a multi-path data update on Firebase when data is changed from the Firebase Console?

I am currently working on an iOS app and I'm using Firebase to power it.
Since my app is still relatively small I'm using the database to often perform manual amends on the data. My users can submit places (that I display on a map) and I review entries manually to ensure the data is complete and correct.
I have recently started using GeoFire and thus had to start denormalizing my data for the coordinates (lat & lon) of each places.
As a result I have coordinates at 2 locations in my database
under /places/place_key/...
under /geofire/place_key/...
I'm currently looking for a way to automatically update the /geofire side of my database when I update the latitude or longitude of a places on the /places side of the database directly from the Firebase Console.
I'm looking for tips on how to do that. Could Firebase Functions help me for this?
Cheers,
Ed
If someone happens to look for an answer to this question in the future, I followed #J. Doe advice and used Firebase Cloud Functions.
The setup is super simple, steps here.
Here is sample code that let's me update several endpoint of my database when one of my object is updated.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.placeDataUpdated = functions.database.ref('/places/{placeId}').onUpdate(event => {
const place = event.data.val();
const key = event.params.placeId;
console.log("Updated place data for key: ", key);
var dataToUpdate = {};
dataToUpdate["places_summary/"+key+"/city"] = place.city;
dataToUpdate["places_summary/"+key+"/country"] = place.country;
dataToUpdate["places_summary/"+key+"/latitude"] = place.latitude;
dataToUpdate["places_summary/"+key+"/longitude"] = place.longitude;
dataToUpdate["places_summary/"+key+"/name"] = place.name;
dataToUpdate["places_summary/"+key+"/numReviews"] = place.numReviews;
dataToUpdate["places_summary/"+key+"/placeScore"] = place.placeScore;
dataToUpdate["places_summary/"+key+"/products"] = place.products;
dataToUpdate["places_summary/"+key+"/visible"] = place.onMap;
dataToUpdate["places_GeoFire/"+key+"/l/0"] = place.latitude;
dataToUpdate["places_GeoFire/"+key+"/l/1"] = place.longitude;
return event.data.ref.parent.parent.update(dataToUpdate);
});
It's super convenient and took next to no time to setup.

iOS - Build polyline from Google Maps Directions API response

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);

How can i get all SKMap location objects so I can filter trough them?

I use SKMap in a offline navigation iOS application and:
I'm trying to search from a UITextField a street/city/district within a preinstalled map and I want to get all objects that matches my search.
How can I get all map location objects so I can filter trough them?
From the sample didn't quite managed to do so.(I get only cities)
Is there other alternative or I must loop trough every city and get streets (Seems ugly)
You have to use SKNearbySearchSettings class and to set
searchObject.searchType = SKAll;
A more detailed example of using this class (should return all streets and POIs containing the "pizza" keyword):
SKNearbySearchSettings *searchObject = [SKNearbySearchSettings nearbySearchSettings];
searchObject.coordinate = CLLocationCoordinate2DMake(52.5233, 13.4127);
searchObject.radius = 40000;
searchObject.searchMode = SKSearchHybrid;
searchObject.searchResultSortType = SKMatchSort;
searchObject.searchType = SKAll;
searchObject.searchTerm = "pizza";
[[SKSearchService sharedInstance]startNearbySearchWithSettings:searchObject];

How to get user's geolocation?

On many sites I saw printed out my current city where I am (eg "Hello to Berlin."). How they do that? What everything is needed for that?
I guess the main part is here javascript, but what everything I need for implementing something like this to my own app? (or is there some gem for Rails?)
Also, I would like to ask for one thing yet - I am interesting in the list of states (usually in select box), where user select his state (let's say Germany), according to the state value are in another select displayed all regions in Germany and after choosing a region are displayed respective cities in the selected region.
Is possible anywhere to obtain this huge database of states/cities/regions? Would be interesting to have something similar in our app, but I don't know, where those lists get...
You need a browser which supports the geolocation api to obtain the location of the user (however, you need the user's consent (an example here) to do so (most newer browsers support that feature, including IE9+ and most mobile OS'es browsers, including Windows Phone 7.5+).
all you have to do then is use JavaScript to obtain the location:
if (window.navigator.geolocation) {
var failure, success;
success = function(position) {
console.log(position);
};
failure = function(message) {
alert('Cannot retrieve location!');
};
navigator.geolocation.getCurrentPosition(success, failure, {
maximumAge: Infinity,
timeout: 5000
});
}
The positionobject will hold latitude and longitude of the user's position (however this can be highly inaccurate in less densely populated areas on desktop browsers, as they do not have a GPS device built in). To explain further: Here in Leipzig in get an accuracy of about 300 meters on a desktop computer - i get an accuracy of about 30 meters with my cell phone's GPS device.
You can then go on and use the coordinates with the Google Maps API (see here for reverse geocoding) to lookup the location of the user. There are a few gems for Rails, if you want. I never felt the need to use them, but some people seem to like them.
As for a list of countries/cities, we used the data obtainable from Geonames once in a project, but we needed to convert it for our needs first.
Internet Service Providers buy up big chunks of IP addresses, so what you're most likely seeing is a backtrace your IP to a known ISP. They have a database with ISP's and their location in the world, so they can try to see where you're from. You could try to use a site like http://www.ipaddresslocation.org/ to do your work. If you look around, there is bound to be a site that lets you enter an IP and get a location, so you just send a POST request to that site with your visitor's IP and scrape the location from the response.
Alternatively you could try to look for an ISP database that has location and what chunks of the IP range they have been allocated. You could probably find one for money, but a free one might be harder to find.
Alternatively, check out this free database http://www.maxmind.com/app/geolite
I've found getCurrentPosition() to often be inaccurate since it doesn't spend a lot of time waiting on the GPS to acquire a good accuracy. I wrote a small piece of JavaScript that mimics getCurrentPosition() but actually uses watch position and monitors the results coming back until they are better accuracy.
Here's how it looks:
navigator.geolocation.getAccurateCurrentPosition(onSuccess, onError, {desiredAccuracy:20, maxWait:15000});
Code is here - https://github.com/gwilson/getAccurateCurrentPosition
Correc syntax would be :
navigator.geolocation.getCurrentPosition(successCallBack, failureCallBack);
Use :
navigator.geolocation.getCurrentPosition(
function(position){
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
console.log("Latitude : "+latitude+" Longitude : "+longitude);
},
function(){
alert("Geo Location not supported");
}
);
If you prefer to use ES6 and promises here is another version
function getPositionPromised() {
function successCb(cb) {
return position => cb(position);
}
function errorCb(cb) {
return () => cb('Could not retrieve geolocation');
}
return new Promise((resolve, reject) => {
if (window.navigator.geolocation) {
navigator.geolocation.getCurrentPosition(successCb(resolve), errorCb(reject));
} else {
return reject('No geolocation support');
}
})
}
And you can use it like this:
getPositionPromised()
.then(position => {/*do something with position*/})
.catch(() => {/*something went wrong*/})
Here is an another api to find out the location in PHP,
http://ipinfodb.com/ip_location_api.php
I have been using geoip.maxmind.com for quite a while and it works 100%. It can be accessed via HTTP requests.

Resources