Doing "Points of Interest Along a Route" in Google Maps

doing points of interest along a route in google maps

Check this out

http://google-maps-utility-library-v3.googlecode.com/svn/tags/routeboxer/1.0/examples/routeboxer-v3.html

Here's the documentation: http://google-maps-utility-library-v3.googlecode.com/svn/tags/routeboxer/1.0/docs/examples.html

You could get the box coordinates from RouteBoxer and send that to a serverside script for processing

Filter POIs that are close to a route

1. You have to find the distance from one POI to the road.

In order to accomplish this, you have to store your road in a mathematical fashion:

  • You can sample equidistant points of your road and store them in an array (more practical, less precise) and then calculate the distance of the POI from every point in the array, then save the minor result and repeat the whole process for every POIs.
  • You can store a road in a function (more and more complex, but more precise). Now that you have this function, you can calculate same distance from your POI, take the minimum value and repeat for all POIs.

2. Google Distance Matrix can actually do this

With this Api you can calculate distance till 2500 origins * destinations points.
The result will give you an array of rows, with each row corresponding

to an origin, and each element within that row corresponds to a pairing of the origin with a destination value.

Example of a request:

https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&origins=32.777211,35.021250&destinations=32.778663,35.015757&key=YOURAPIKEY

This is very useful to your goal, because lets you specify more than one points of which calculates distance.

Find POI along a Google Maps route? (Android)

First things first:

1) do you have latlng (geolocations) variable type in your database?

If answer(1) == yes:
Calculate and query your database: D²=(Xb-Xa)²+(Yb-Ya)² along each of your Xa,Ya route points to discover the POIs (Ya,Yb) within Distance = D.

How do I draw a route, along an existing road, between two points?

Indeed, you can draw precise route in Google Maps Android API using results provided by Directions API web service. If you read the documentation for Directions API you will see that response contains information about route legs and steps. Each step has a field polyline that is described in the documentation as

polyline contains a single points object that holds an encoded polyline representation of the step. This polyline is an approximate (smoothed) path of the step.

So, the main idea to solve your issue is to get response from Directions API, loop through route legs and steps, for each step get encoded polyline and decode it to the list of coordinates. Once done you will have a list of all coordinates that compound the route, not only begin and end point of each step.

For simplicity I recommend using the Java client library for Google Maps Web services:

https://github.com/googlemaps/google-maps-services-java

Using this library you can avoid implementing your own async tasks and decoding function for polylines. Read the documentation to figure out how to add the client library in your project.

In Gradle it should be something similar to

compile 'com.google.maps:google-maps-services:(insert latest version)'
compile 'org.slf4j:slf4j-nop:1.7.25'

I have created a simple example to demonstrate how it works. Have a look at my comments in the code

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

private GoogleMap mMap;
private String TAG = "so47492459";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}

@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;

LatLng barcelona = new LatLng(41.385064,2.173403);
mMap.addMarker(new MarkerOptions().position(barcelona).title("Marker in Barcelona"));

LatLng madrid = new LatLng(40.416775,-3.70379);
mMap.addMarker(new MarkerOptions().position(madrid).title("Marker in Madrid"));

LatLng zaragoza = new LatLng(41.648823,-0.889085);

//Define list to get all latlng for the route
List<LatLng> path = new ArrayList();

//Execute Directions API request
GeoApiContext context = new GeoApiContext.Builder()
.apiKey("YOUR_API_KEY")
.build();
DirectionsApiRequest req = DirectionsApi.getDirections(context, "41.385064,2.173403", "40.416775,-3.70379");
try {
DirectionsResult res = req.await();

//Loop through legs and steps to get encoded polylines of each step
if (res.routes != null && res.routes.length > 0) {
DirectionsRoute route = res.routes[0];

if (route.legs !=null) {
for(int i=0; i<route.legs.length; i++) {
DirectionsLeg leg = route.legs[i];
if (leg.steps != null) {
for (int j=0; j<leg.steps.length;j++){
DirectionsStep step = leg.steps[j];
if (step.steps != null && step.steps.length >0) {
for (int k=0; k<step.steps.length;k++){
DirectionsStep step1 = step.steps[k];
EncodedPolyline points1 = step1.polyline;
if (points1 != null) {
//Decode polyline and add points to list of route coordinates
List<com.google.maps.model.LatLng> coords1 = points1.decodePath();
for (com.google.maps.model.LatLng coord1 : coords1) {
path.add(new LatLng(coord1.lat, coord1.lng));
}
}
}
} else {
EncodedPolyline points = step.polyline;
if (points != null) {
//Decode polyline and add points to list of route coordinates
List<com.google.maps.model.LatLng> coords = points.decodePath();
for (com.google.maps.model.LatLng coord : coords) {
path.add(new LatLng(coord.lat, coord.lng));
}
}
}
}
}
}
}
}
} catch(Exception ex) {
Log.e(TAG, ex.getLocalizedMessage());
}

//Draw the polyline
if (path.size() > 0) {
PolylineOptions opts = new PolylineOptions().addAll(path).color(Color.BLUE).width(5);
mMap.addPolyline(opts);
}

mMap.getUiSettings().setZoomControlsEnabled(true);

mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(zaragoza, 6));
}
}

Please note that for web service you have to create a separate API key, the API key with Android app restriction won't work with web service.

The result of my example is shown in screenshot

Sample Image

You can also download a complete sample project from

https://github.com/xomena-so/so47492459

Don't forget replace the API key with yours.

I hope this helps!

Get exact geo coordinates along an entire route, Google Maps or OpenStreetMap

OSRM gives you routes with road geometries as they are in the OpenStreetMap database. For example, you can get the route as GPX (and post-process this file if you want). This would look like the following:

GET http://router.project-osrm.org/viaroute?hl=en&loc=47.064970,15.458470&loc=47.071100,15.476760&output=gpx

Read more: OSRM API docs.

Algorithm to find Points of Interest along a route?

Assuming you have your POI points indexed in some space partitioning data structure as a k-d tree or a quadtree, implementing a find-points-near-polyline algorithm shouldn't be too difficult.

  1. From the polyline obtain the set of segments conforming it.
  2. Descend recursively into your space partitioning data strucure filtering at every level the set of segments by the distance to the space partition enclosing box.
  3. Once you reach a final node, use brute force to check the distance between the remaining vectors in the set at that point and the POI in the partition.

Points within n km's of route / path

In general, you have to find distance from a given point (your customer) and a polyline (the route). The route from the google directions response is divided into legs, and the leg is consisted of multiple steps... In each step, you have path[] array of locations (pair of latitude and longitude). Let's call each location in the path[] array, a "Vertex".
You have to iterate through all vertices in the route (get all vertices from all steps in the route) and calculate the distance between the polyline created from the current "observed" vertices and the yours POI (Points of Interest - the Customers)
The shortest distance can be calculated by presenting the two vertices & the Customer's location as nVector. After this, by doing Vector cross product of the vectors you find the shortest (orthogonal) distance between the point and the polyline
I had similar problem recently and I solved it that way. I got the idea from the examples Here (look at the DISTANCE POINT TO POLYLINE OR POLYGON example Source code)

If you are confused from the Math involved, maybe this link might help you by explaining the concept of a Vector Cross Product. Also this could also help you to understand the nVector concept.

Because this kind of calculating the distance is pretty much time consuming (if you have many customer locations in the database), you might be interested of filtering some of the locations from the database and not performing calculations for them...look at my answer on this question about how to do filtering on locations based on the route that is shown on the map.
Hope this helps and give you some basic idea on how to start solving your problem. It took me a lot of time till to figure it out. Cheers.



Related Topics



Leave a reply



Submit