11
$\begingroup$

I have following graph.

    g = Graph[{"Uppsala" -> "Marsta", "Marsta" -> "Uppsala", 
    "UpplandsVasby" -> "Sollentuna", "Sollentuna" -> "UpplandsVasby", 
    "UpplandsVasby" -> "Marsta", "Marsta" -> "UpplandsVasby", 
    "Stockholm" -> "Boo", "Boo" -> "Stockholm", 
    "Stockholm" -> "Lidingo", "Lidingo" -> "Stockholm", 
    "Stockholm" -> "Sollentuna", "Sollentuna" -> "Stockholm", 
    "Stockholm" -> "Taby", "Taby" -> "Stockholm"}, 
   VertexLabels -> "Name", ImagePadding -> 40];

coords = CityData[#, "Coordinates"] & /@ VertexList[g];

SetProperty[g, {VertexCoordinates -> Reverse[coords, 2], 
  Prolog -> {Gray, CountryData["Sweden", "Polygon"]}}]

Based on the real road connection on the GoogleMap or other GPS data ,how can I set my Edgecover the actual road connection between cities and the actual distance(in Km) based on the GoogleMap stays as a EdgeCost. For example,I want to set these two cities as two vertexes of the my edge in the graph "Uppsala" -> "Marsta"(which is already). But as you can see the edge between two cities is just an arrow connecting two geographical locations of cities.I wanted them to use GoogleMap(or other GPS data) and set my edge on the map based on the shortest suggested route of GoogleMap.And set the calculated distance as EdgeCost value of created edge.Is it possible?

$\endgroup$
2
  • $\begingroup$ For example,I want to set these two cities as two vertexes of the my edge in the graph "Uppsala" -> "Marsta"(which is already). But as you can see the edge between two cities is just an arrow connecting two geographical locations of cities.I wanted them to use GoogleMap(or other GPS data) and set based on the shortest suggested route of GoogleMap as my edge on the map.And set the calculated distance as EdgeCost value of created edge. $\endgroup$
    – Alex
    May 24, 2013 at 3:10
  • $\begingroup$ Hi,many thanks but this is not just about importing data from GoogleMap.It is about how to set the required data in the Graph. Please read the question again.Thanks $\endgroup$
    – Alex
    May 24, 2013 at 3:23

2 Answers 2

5
$\begingroup$

Here's a piece of the puzzle:

c1 = CityData["Boston", "Coordinates"];
c2 = CityData["New York", "Coordinates"];
address = "http://maps.googleapis.com/maps/api/distancematrix/json?origins=" <>
    ToString[c1[[1]]] <> "," <> ToString[c1[[2]]] <> "&destinations=" <>
    ToString[c2[[1]]] <> "," <> ToString[c2[[2]]] <> "&sensor=false"

which I modified from the google directions API. Now you can get the data from google:

distData = Import[address]

Per rm-rf's suggestion, you can get cleaner (easier to parse input) using

distData = Import[address, "JSON"]

which gives

{"destination_addresses" -> {"801 Montgomery Street, Brooklyn, NY 11213, USA"}, 
 "origin_addresses" -> {"Head Island Causeway, Boston, MA 02127, USA"}, 
 "rows" ->  {{"elements" -> {{"distance" -> {"text" -> "349 km", "value" -> 349019}, 
              "duration" -> {"text" -> "3 hours 45 mins", "value" -> 13477}, 
              "status" -> "OK"}}}}, 
 "status" -> "OK"}

Indexing into this

First[First[distData[[3, 2]]]][[2, 1, 1, 2, 1]]

gives

"text" -> "349 km"
$\endgroup$
4
  • $\begingroup$ I think you could do Import[..., "JSON"] for cleaner data $\endgroup$
    – rm -rf
    May 24, 2013 at 7:19
  • 1
    $\begingroup$ I think we have to be aware of this detail: "Use of the Distance Matrix API must relate to the display of information on a Google Map; for example, to determine origin-destination pairs that fall within a specific driving time from one another, before requesting and displaying those destinations on a map. Use of the service in an application that doesn't display a Google map is prohibited.". This information can be accessed here $\endgroup$
    – Rod
    May 24, 2013 at 8:25
  • 1
    $\begingroup$ Some syntax sugestion address=ToString@StringForm["http://maps.googleapis.com/maps/api/distancematrix/json?origins=`1`,`2`&destinations=`3`,`4`&sensor=false",c1[[1]],c1[[2]],c2[[1]],c2[[2]]] and a more general way to parse JSON Cases[distData, HoldPattern["distance" -> {_ -> km_, _} ] :> km , \[Infinity]] $\endgroup$
    – Murta
    May 25, 2013 at 4:59
  • $\begingroup$ As of MMA 11 you can have a look at 'TavelDistance' $\endgroup$
    – Eisbär
    Jan 13, 2017 at 16:05
3
$\begingroup$

This is only an attempt to answer the question, if I understood it correctly. You want to "cover the actual road connection between cities (...) based on the GoogleMap".

First step: find the coordinates of the two cities you want to use as edges in your graphic:

c1 = CityData["Sao Paulo", "Coordinates"];
c2 = CityData["Rio de Janeiro", "Coordinates"];

Second step: define the center of the map:

center = (c1 + c2)/2;

Third step: Import[] the actual Google Maps image based on the center you've specified

Import["http://maps.google.com/maps/api/staticmap?center=" <>ToString[center[[1]]] <> "," <> ToString[center[[2]]] <> "&zoom=6&size=400x400&sensor=false&maptype=roadmap&markers=color:blue%7Clabel:O%7C" <> ToString[c1[[1]]] <> "," <> ToString[c1[[2]]] <>"&markers=color:red%7Clabel:D%7C" <> ToString[c2[[1]]] <> "," <> ToString[c2[[2]]]]

enter image description here

EDITED

After some research, I think it can also be done:

Define the cities:

from = ToString[c1[[1]]] <> "," <> ToString[c1[[2]]];
to = ToString[c2[[1]]] <> "," <> ToString[c2[[2]]];

Now use Mathematica to import data from Google with distance and time:

distdata = Import["http://maps.googleapis.com/maps/api/directions/json?origin=" <> from <> "&destination=" <> to <> "&region=es&sensor=false", {"HTML", "Source"}];

Now find distance by road:

roadDistance = StringSplit[StringSplit[distdata, ":"][[13]],","][[1]]

"429 km"

Now find travel time:

travelTime = StringSplit[StringSplit[distdata, ":"][[16]], ","][[1]]

"4 hours 44 mins"

$\endgroup$
8
  • 2
    $\begingroup$ I presume what the OP means with the quoted sentence is that they want to set the cost of the edge between the two cities (which are the vertices) to be equal to the distance (on road, which is why they're using Google maps) between them. This edge cost will, perhaps, be used in optimization/TSP/other algorithms to calculate the cost in moving something from A to B/finding the cheapest route (not necessarily the fastest/shortest), etc. $\endgroup$
    – rm -rf
    May 24, 2013 at 5:47
  • $\begingroup$ @rm-rf YES you are right.The whole problem is to optimize the graph cost based on the GoogleMap real distances.Any idea how to do that? $\endgroup$
    – Alex
    May 24, 2013 at 6:21
  • $\begingroup$ @Alex So you actually don't need to create a graphic? You need to compute distances based on Google Maps/GPS? So I think it would be interesting to edit the question and put something more clear like "Can I use Google Maps or GPS data to compute road distances"? $\endgroup$
    – Rod
    May 24, 2013 at 6:29
  • $\begingroup$ @RodLm many thanks!! please read it carefully it is not "graphic".It is Graph.Yes!!! in the beginning, it has to compute the road distances and this is part of the solution but not all.In the end, I want to show my Graph (inducing vertexes and edges(real roads))on GoogleMap picture.Any idea? $\endgroup$
    – Alex
    May 24, 2013 at 6:39
  • $\begingroup$ @Alex If you want to compute distances using Google Maps I think one approach is to decode the Google Directions API polylines and compute distances directly from it... I know it can be done in C# and Java... However I'm stil wondering how to do this with Mathematica. $\endgroup$
    – Rod
    May 24, 2013 at 6:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.