50
$\begingroup$

GoogleMaps are implemented as HTML and Javascript code which can be viewed by a web browser. Is it possible to load this map into the Mathematica notebook, which obviously means for example that

<script src="http://maps.google.com/maps?file=api&amp;v=2.s&amp;key="
    type="text/javascript">
</script>
<script src="/Users/meinmacbookpro/Desktop/Messprojekte/gps.js" 
    type="text/javascript">
</script>

should be implemented somehow into the Mathematica code?

$\endgroup$
50
$\begingroup$

All we need to create an interactive Google Map in the notebook is access to the individual tiles - and there is a relatively simple naming scheme for those tiles. The most basic form of a tile URL looks like: http://mt0.google.com/vt/x=xi&y=yi&z=i, where $0\leq xi,yi < 2^i$. For example, at zoom level z=0, there is one tile representing the whole earth:

http://mt0.google.com/vt/x=0&y=0&z=0

enter image description here

At zoom level 1, there are 4 tiles that cover most of the earth:

enter image description here

With a little understanding of the Mercator projection, it's not hard to translate from lat/lng values to tile indices:

{alng,blng} = First[{a,b} /. Solve[
  {a*(-180)+b==0,a(180)+b==1},{a,b}]];
lngToIndex[lng_, zoom_] := Floor[(alng*lng+blng)2^zoom];
mercator[lat_] = Log[Abs[Sec[lat*Degree]+Tan[lat*Degree]]];
{alat,blat} = First[{a,b} /. Solve[{a*mercator[85.0511287798066]+b==0,
  a*mercator[-85.0511287798066]+b==1},{a,b}]];
latToIndex[lat_, zoom_] := Floor[(alat*mercator[lat]+blat)2^zoom];
indicesToTileURL[x_Integer, y_Integer, zoom_Integer] := 
  "http://mt0.google.com/vt/x=" <> ToString[x] <> "&y=" <> 
    ToString[y] <> "&z=" <> ToString[zoom]

Now, suppose I'd like to compute the URL of a tile in my neighborhood.

{lat0,lng0} = CityData["Asheville", "Coordinates"];
x0=lngToIndex[lng0,10];
y0=latToIndex[lat0,10];
indicesToTileURL[x0,y0,10]

"http://mt0.google.com/vt/x=277&y=403&z=10"

We can put this all together to set up an interactive zoomer.

Manipulate[
  With[{x0=lngToIndex[lng0,zoom],y0=latToIndex[lat0,zoom]},
    Grid[{
      {Import[indicesToTileURL[x0-1,y0-1,zoom]],
       Import[indicesToTileURL[x0,y0-1,zoom]],
       Import[indicesToTileURL[x0+1,y0-1,zoom]]},
       {Import[indicesToTileURL[x0-1,y0,zoom]],
       Import[indicesToTileURL[x0,y0,zoom]],
       Import[indicesToTileURL[x0+1,y0,zoom]]},
      {Import[indicesToTileURL[x0-1,y0+1,zoom]],
       Import[indicesToTileURL[x0,y0+1,zoom]],
       Import[indicesToTileURL[x0+1,y0+1,zoom]]}
    }, Spacings -> {0,0}]
  ],{{zoom,13},Range[2,18]}]

enter image description here

This is really just proof of concept at this point. There's quite a lot more that could be done. You could use an EventHandler to allow dragging and panning and add other controls as well. You'd need some error handling to deal with scrolling out of range. You could also interface other map servers.

Also, I checked the terms of use of the Google Maps API available here: http://www.google.com/intl/en_us/help/terms_maps.html

I don't see anything that violates their terms of use but, then, I'm not a lawyer.

$\endgroup$
  • $\begingroup$ wow, thanks a lot. I will deeply go into your answer tomorrow on Sunday. Thanks a lot, Harald $\endgroup$ – Harald Mar 24 '12 at 17:25
  • $\begingroup$ @Harald No problem - it's great fun! I'd be curious to hear more about the specific application you have in mind. $\endgroup$ – Mark McClure Mar 24 '12 at 17:36
  • $\begingroup$ The application calculates points for some grids (usually 40 m by 40 m) for geophysical mappings of archaeological sites, as an input for the Leica GPS900. And the combination with a (for example) Google Map should be good for the documentation of the field campaign. $\endgroup$ – Harald Mar 25 '12 at 7:48
  • $\begingroup$ @MarkMcClure It appears that the facstaff.unca.edu in both the question and this answer are dead. If this is not a temporary failure would you fix them if possible? It appears that the Google Maps URL format may also have changed. $\endgroup$ – Mr.Wizard Jul 25 '18 at 22:53
  • 2
    $\begingroup$ @Mr.Wizard I finally got round to updating this post and question removing all references to my now dead site. I think the material that is left stands on its own. I also flagged a comment on the original question that is now irrelevant and should probably be deleted. $\endgroup$ – Mark McClure Jul 22 at 12:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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