google maps static map polyline passing through lakes, river, mountains
Asked Answered
D

2

-1

My program uses google maps directions for web Services to find a route between two points. The result is parsed and stored in variable.
This variable is then used to compose google static map URL.

The parse and the URL are working correctly. The problem is that the drawn "route" passes through a lake and mountains.

{
    String GPS = "-22.978823,-43.233249";
    String link = MAPS_BASE_URL + "center=brazil," + GPS + 
            "&markers=color:blue|brazil," + GPS +
            "&path=color:0xff0000ff" + "%s" + 
            "&zoom=13&size=1024x1024&sensor=false"; 
    String htmlContent = "";
    String direction_URL= "";

    URL url = null;
    String parsedStr = null;
    Scanner scan = null;

    origin = GPS;
    destination ="Maracanã";

    try { 
        direction_URL = MAPS_DIRECTIONS_URL;    
        direction_URL += URLEncoder.encode(origin, "UTF-8");
        direction_URL += "&destination=";
        direction_URL += URLEncoder.encode(destination, "UTF-8");
        direction_URL += "&key=AIzaSyARNFl6ns__p2OEy3uCrZMGem8KW8pXwAI";
    }catch(UnsupportedEncodingException e){
         Logger.getLogger(Service.class.getName()).log(Level.SEVERE, null, e);
    }

    try {
        url = new URL(direction_URL);
    } catch (MalformedURLException ex) {
        Logger.getLogger(AlertService.class.getName()).log(Level.SEVERE, null, ex);
    }

    try {
        scan = new Scanner(url.openStream());
    } catch (IOException ex) {
        Logger.getLogger(AlertService.class.getName()).log(Level.SEVERE, null, ex);
    }

    String str = new String();
    while (scan.hasNext())
        str += scan.nextLine();
    scan.close();

    parsedStr = parseJson(str);

    try {
        InputStream htmlInputStream = 
                AlertService.class.getResourceAsStream("/resources/gapi.html");

        BufferedReader htmlReader = new BufferedReader(
                new InputStreamReader(htmlInputStream));

        String locationsContent = "";
        String wilcardContent = "";

        Scanner strScanner = new Scanner(parsedStr);

        while (strScanner.hasNextLine()) 
        {
            locationsContent = strScanner.nextLine() + "\n";

            StringTokenizer st = new StringTokenizer(locationsContent, ";");
            if (st.countTokens() == 2)
                wilcardContent += "|" + st.nextToken().trim()
                        + "," + st.nextToken().trim();
        }
        link = link.replaceFirst("%s", wilcardContent);

        htmlContent = "";
        while (htmlReader.ready()) 
            htmlContent += htmlReader.readLine() + "\n";

        htmlContent = htmlContent.replaceAll("%s", link);

     } catch (FileNotFoundException ex) {
        Logger.getLogger(Service.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
        Logger.getLogger(Service.class.getName()).log(Level.SEVERE, null, ex);
    } 
   return htmlContent;
}

Parse function:

 private String parseJson(String s){
    String  coordinates = new String ();
    final JSONObject json = new JSONObject(s);
    final JSONObject jsonRoute = json.getJSONArray("routes").getJSONObject(0);
    //Get the leg, only one leg as we don't support waypoints
    final JSONObject leg = jsonRoute.getJSONArray("legs").getJSONObject(0);
    //Get the steps for this leg
    final JSONArray steps = leg.getJSONArray("steps");
    //Number of steps for use in for loop
    final int numSteps = steps.length();

    for(int i = 0; i< numSteps; ++i){
        final JSONObject step = steps.getJSONObject(i);

        final JSONObject startLocation = step.getJSONObject("start_location");
        final Double startLat = startLocation.getDouble("lat");
        final Double startlng = startLocation.getDouble("lng");

        final JSONObject endLocation = step.getJSONObject("end_location");
        final Double endtLat = endLocation.getDouble("lat");
        final Double endtlng = endLocation.getDouble("lng");

        coordinates = coordinates.concat(" ");    
        coordinates = coordinates.concat(startLat.toString());
        coordinates = coordinates.concat(";" + " ");
        coordinates = coordinates.concat(startlng.toString());
        coordinates = coordinates.concat("\n");  

        coordinates = coordinates.concat(" ");    
        coordinates = coordinates.concat(endtLat.toString());
        coordinates = coordinates.concat(";" + " ");
        coordinates = coordinates.concat(endtlng.toString());
        coordinates = coordinates.concat("\n");      
    } 
    return coordinates;     
}

Json response:

https://maps.googleapis.com/maps/api/directions/json?origin=-22.978823,-43.233249&destination=Maracan%C3%A2&key=AIzaSyARNFl6ns__p2OEy3uCrZMGem8KW8pXwAI

The Final URL look like this:

http://maps.google.com/maps/api/staticmap?center=brazil,-22.978823,-43.233249&markers=color:blue|brazil,-22.978823,-43.233249&path=color:0xff0000ff|-22.9783362,-43.2336781|-22.9772355,-43.23076390000001|-22.9772355,-43.23076390000001|-22.9789792,-43.2300162|-22.9789792,-43.2300162|-22.9790772,-43.23036|-22.9790772,-43.23036|-22.9786979,-43.22698949999999|-22.9786979,-43.22698949999999|-22.9771399,-43.2196208|-22.9771399,-43.2196208|-22.9624962,-43.20396840000001|-22.9624962,-43.20396840000001|-22.9583858,-43.2043807|-22.9583858,-43.2043807|-22.934896,-43.2094454|-22.934896,-43.2094454|-22.9333061,-43.2096873|-22.9333061,-43.2096873|-22.913577,-43.2099889|-22.913577,-43.2099889|-22.9106681,-43.2154625|-22.9106681,-43.2154625|-22.9101261,-43.2217923|-22.9101261,-43.2217923|-22.9114561,-43.2254838|-22.9114561,-43.2254838|-22.9135546,-43.2276606&zoom=13&size=1024x1024&sensor=false

Detradetract answered 27/8, 2015 at 17:0 Comment(10)
What does the generated URL look like that has the issue?Manouch
Where does that route come from? Looks like it comes from the directions service but doesn't include all the points (just the start and end of each leg).Manouch
@Manouch I added the static map URL. In addition, route indeed comes from the directions service.Detradetract
What does the directions request/response that it comes from look like? It looks to me (as as said in my second comment) that you are only including some of the points in the directions response. You probably want to encode the path as well.Manouch
@Manouch Could you provide me an example of how you dit it?Detradetract
What was the source of your data? The Directions Web Service or the Google Maps Javascript API v3? You didn't post that in your question.Manouch
@Manouch The web serviceDetradetract
@Manouch On your answer, you first decode each polyline and then for each decoded value, you store it on path variable using push. How does path look like after leaving for loop? In my code I'm decoding a String and encoding ithe resault, but it gives me the same reply I got before decoding.Detradetract
The jsfiddle in my answer is computing the path. It works, compare what it is doing to whatever you are doing that isn't working.Manouch
See also https://mcmap.net/q/505284/-show-a-route-on-a-map/… (might help)Yingling
D
0

I figured out how to solve it in java.I adapted user geocozip javascript code. In my case, as no waypoints are provided, I just need one leg. So my parse function got this:

  List<LatLng> path = new ArrayList();
  for(int j = 0; j< numSteps; ++j){
    final JSONObject step = steps.getJSONObject(j);

    final JSONObject polyline = step.getJSONObject("polyline");
    final String polylinePoint = polyline.getString("points");


    List<LatLng> coordinates = decodePath(polylinePoint);
    for( int k = 0; k < coordinates.size(); ++k){
        path.add(coordinates.get(k));
    }
 } 

It is also necessary re-encode and then put in a format URL readable.

String newPath = path.createPolyLine(encodedPath);
String locationsContent="";
locationsContent = URLEncoder.encode(newPath, "UTF-8")
        .replaceAll("\\%40", "@")
        .replaceAll("\\+", "%20")
        .replaceAll("\\%21", "!")
        .replaceAll("\\%27", "'")
        .replaceAll("\\%28", "(")
        .replaceAll("\\%29", ")");
Detradetract answered 14/9, 2015 at 1:59 Comment(0)
M
0

You need to include the polyline path between each step's start and end points (it is an encoded polyline).

From the directions web service response:

 "steps" : [
    {
       "distance" : {
          "text" : "0.3 km",
          "value" : 335
       },
       "duration" : {
          "text" : "1 min",
          "value" : 52
       },
       "end_location" : {
          "lat" : -22.9772355,
          "lng" : -43.23076390000001
       },
       "html_instructions" : "Head \u003cb\u003enortheast\u003c/b\u003e on \u003cb\u003eR. Marquês de São Vicente\u003c/b\u003e",
       "polyline" : {
          "points" : "r}fkCna{fGyBaDMSMSOUMUCMAOOgAEe@Co@?o@?YAWEk@?G"
       },
       "start_location" : {
          "lat" : -22.9783362,
          "lng" : -43.2336781
       },
       "travel_mode" : "DRIVING"
     },
     // ...

Including all the step polylines (and encoding the polyline) works for me

jsfiddle creating a URL for the static map from the web service response

Manouch answered 27/8, 2015 at 18:46 Comment(2)
Could you provide me an example of how you dit it?Detradetract
added example of parsing the directions service response to my answerManouch
D
0

I figured out how to solve it in java.I adapted user geocozip javascript code. In my case, as no waypoints are provided, I just need one leg. So my parse function got this:

  List<LatLng> path = new ArrayList();
  for(int j = 0; j< numSteps; ++j){
    final JSONObject step = steps.getJSONObject(j);

    final JSONObject polyline = step.getJSONObject("polyline");
    final String polylinePoint = polyline.getString("points");


    List<LatLng> coordinates = decodePath(polylinePoint);
    for( int k = 0; k < coordinates.size(); ++k){
        path.add(coordinates.get(k));
    }
 } 

It is also necessary re-encode and then put in a format URL readable.

String newPath = path.createPolyLine(encodedPath);
String locationsContent="";
locationsContent = URLEncoder.encode(newPath, "UTF-8")
        .replaceAll("\\%40", "@")
        .replaceAll("\\+", "%20")
        .replaceAll("\\%21", "!")
        .replaceAll("\\%27", "'")
        .replaceAll("\\%28", "(")
        .replaceAll("\\%29", ")");
Detradetract answered 14/9, 2015 at 1:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.