The
WebView
is created in
activity_main.xml
.
See the
WebView
tutorial,
Debugging
Web Apps,
and
Google Maps
Android API v2.
The
WebView
has two client objects.
The
WebViewClient
has a method that is called when the
WebView
has finished loading its web page.
The
WebChromeClient
has method that is called whenever the web page calls the JavaScript
alert
function.
When the page is loaded,
the
onPageFinished
method of the
WebViewClient
calls the JavaScript function
mapFunction
,
which fills the
div
element with a Google Map.
If we forget to set the height
of the
body
and
html
elements,
the
div
will have a height of zero.
I wonder why we didn’t have to set the widths, too.
MainActivity.java
activity_main.xml
contains a
WebView
.
map.html
in the
assets
folder.
AndroidManifest.xml
:
a
WebView
requires
uses-permission
INTERNET
.
The
map.html
to which the URL refers must be in the assets folder in the
Android Studio
project
view.
Select the app folder at the top of the
project
view.
Pull down
File → New… → Folder → Assets Folder
Finish
Remember to add the
uses-permission
to
AndroidManifest.xml
.
Select the
assets
folder in the left pane of Android Studio.
File →
New… →
File
Enter a new filename: map.html
OK
map.html
that calls
alert
.
This will call the
onJsAlert
method of the
WebChromeClient
.
map.html
that creates the
Marker
.
Why can’t we get the marker’s
title
to appear?
Point your desktop browser at
map2.html
.
It’s exactly the same as the
map.html
in the project, except that
no Android app is necessary to see the map.
(As soon as
map2.html
is loaded into your desktop browser,
the JavaScript
mapFunction
is called automatically by the
onLoad
attribute of the
BODY
element in
map2.html
.)
When you hover over the marker
(i.e., hold your mouse there without clicking),
the marker’s title will appear after a few seconds.
And in fact the
documentation for
title
defines the title as “rollover text”.
Maybe the title doesn’t appear in an Android app
simply because there is no way to do a rollover on a mobile app.
An alternative is to give the marker a
label
instead of a
title.
After the first
SCRIPT
element, include this one too:
<SCRIPT SRC = "http://google-maps-utility-library-v3.googlecode.com/svn/tags/markerwithlabel/1.0.1/src/markerwithlabel.js"> </SCRIPT>Create the marker like this:
var style = 'color: white;' + 'text-shadow:' + '-1px -1px 3px black,' + '1px -1px 3px black,' + '-1px 1px 3px black,' + '1px 1px 3px black;'; var labelContent = '<SPAN STYLE = "' + style + '">Woolly Building</SPAN>'; options = { position: position, //We created this variable earlier. map: map, //We created this variable earlier. icon: 'http://maps.google.com/mapfiles/ms/micons/red-dot.png', labelContent: labelContent, labelAnchor: new google.maps.Point(22, 0), labelClass: 'labels', //the CSS class for the label labelStyle: {opacity: 0.75} }; var marker = new MarkerWithLabel(options);
map.html
that creates the
InfoWindow
.
mapFunction
in
map.html
,
change
HYBRID
to
ROADMAP
,
SATELLITE
,
or
TERRAIN
.
ROADMAP
or
HYBRID
.
Decrease the zoom level to 12
in the
onPageFinished
method of the
WebViewClient
.
Then add the following statements to the
mapFunction
in
map.html
,
immediately after the statement that creates the
map
variable.
var trafficLayer = new google.maps.TrafficLayer(); trafficLayer.setMap(map);What about the bicycling layer?
A Google map is made of tiles.
Each tile is a separate image file,
usually of 256 × 256 pixels.
Each tile has a URL.
The URL of the following tile at zoom level 0 is
http://mt1.google.com/vt/x=0&y=0&z=0
At zoom level 1, the map is 2 tiles wide and 2 tiles high.
mt1.google.com/vt/x=0&y=0&z=1
|
mt1.google.com/vt/x=1&y=0&z=1
|
mt1.google.com/vt/x=0&y=1&z=1
|
mt1.google.com/vt/x=1&y=1&z=1
|
The URLs of the following tiles begin with
http://mw1.google.com/mw-planetary/lunar/lunarmaps_v1/clem_bw/
http://mw1.google.com/mw-planetary/lunar/lunarmaps_v1/clem_bw/0/0/0.jpg
.
At zoom level 0, the entire map is 1 tile wide and 1 tile high.
0/0/0.jpg |
the corresponding tile for the Earth |
At zoom level 1, the map is 2 tiles wide and 2 tiles high.
1/0/1.jpg |
1/1/1.jpg |
1/0/0.jpg |
1/1/0.jpg |
At zoom level 2, the map is 4 tiles wide and 4 tiles high.
2/0/3.jpg |
2/1/3.jpg |
2/2/3.jpg |
2/3/3.jpg |
2/0/2.jpg |
2/1/2.jpg |
2/2/2.jpg |
2/3/2.jpg |
2/0/1.jpg |
2/1/1.jpg |
2/2/1.jpg |
2/3/1.jpg |
2/0/0.jpg |
2/1/0.jpg |
2/2/0.jpg |
2/3/0.jpg |
To see
Tycho,
the most conspicuous crater on the Moon,
change the contents of the
map.html
file to the following.
<!DOCTYPE html> <html style = "height: 100%;"> <head> <meta charset = "utf-8"> <script type = "text/javascript" src = "http://maps.google.com/maps/api/js?sensor=false"> </script> <script type = "text/javascript"> function MoonMapType() {} //constructor MoonMapType.prototype.name = "Moon"; MoonMapType.prototype.alt = "Clementine Moon Map"; MoonMapType.prototype.minZoom = 0; MoonMapType.prototype.maxZoom = 9; MoonMapType.prototype.radius = 1738000; //of Moon in meters MoonMapType.prototype.tileSize = new google.maps.Size(256, 256); MoonMapType.prototype.getTile = function(coord, zoom, ownerDocument) { //The map is n by n tiles, where n == 2 ** zoom. var n = 1 << zoom; //Can't go above the north pole or below the south pole, var y = coord.y; if (y < 0 || y >= n) { return null; } //but can go round and round forever in the east/west direction. var x = coord.x % n; if (x < 0) { x += n; } var img = ownerDocument.createElement("img"); img.src = "http://mw1.google.com/mw-planetary/lunar/lunarmaps_v1" + "/clem_bw/" + zoom + "/" + x + "/" + (n - y - 1) + ".jpg"; return img; }; //This function is called by the onPageFinished method of the //WebViewClient. function mapFunction(latitude, longitude, zoom) { var options = { center: new google.maps.LatLng(latitude, longitude), mapTypeControl: false, scaleControl: true, zoom: zoom }; var map = new google.maps.Map(document.getElementById("map"), options); map.mapTypes.set("moon", new MoonMapType()); //add to map's registry map.setMapTypeId("moon"); } </script> </head> <body style = "height: 100%; margin: 0px; padding: 0px;"> <div id = "map" style = "width: 100%; height: 100%;"> </div> </body> </html>
Change the latitude to
-43.0f
,
the longitude to
-11.2f
,
and the zoom level to
4
.
To see
Orion
the Hunter,
the most conspicuous constellation in the sky,
change
img.src
to
img.src = "http://mw1.google.com/mw-planetary/sky/skytiles_v1/" + coord.x + "_" + coord.y + '_' + zoom + '.jpg';Change the maximum zoom level to 13 and the radius to I don’t know what. Does the sky even have a radius? Change the latitude to
-1.0f
,
the longitude to
6.44f * 360.0f / 24.0f
,
and the zoom level to
5
.
Betelgeuse
is to the upper left,
Rigel
to lower right.
Latitude and longitude are called
declination
and
right ascension
when you’re up in the sky.
The right ascension of Orion should be about 5½ hours.
I don’t understand why I had to ask for 6.44.
The URL of each tile begins with
http://mw1.google.com/mw-planetary/mars/visible/
.http://mw1.google.com/mw-planetary/mars/visible/t.jpg
.qrst
names of the tiles make the JavaScript more complicated.
At zoom level 0,
the map is 1 tile wide and 1 tile high.
t.jpg |
At zoom level 1, the map is 2 tiles wide and 2 tiles high.
tq.jpg |
tr.jpg |
tt.jpg |
ts.jpg |
At zoom level 2, the map is 4 tiles wide and 4 tiles high.
tqq.jpg |
tqr.jpg |
trq.jpg |
trr.jpg |
tqt.jpg |
tqs.jpg |
trt.jpg |
trs.jpg |
ttq.jpg |
ttr.jpg |
tsq.jpg |
tsr.jpg |
ttt.jpg |
tts.jpg |
tst.jpg |
tss.jpg |
To see
Olympus Mons,
the most conspicuous volcano on Mars,
change the contents of the
map.html
file to the following.
Change the latitude to
18.4f
,
the longitude to
226.75f
,
and the zoom to
7
.
<!DOCTYPE html> <html style = "height: 100%;"> <head> <meta charset = "utf-8"> <script type = "text/javascript" src = "http://maps.google.com/maps/api/js?sensor=false"> </script> <script type = "text/javascript"> function MarsMapType() {} //constructor MarsMapType.prototype.name = "Mars"; MarsMapType.prototype.alt = "JPL Mars Map"; MarsMapType.prototype.minZoom = 0; MarsMapType.prototype.maxZoom = 9; MarsMapType.prototype.radius = 3396200; //of Mars in meters MarsMapType.prototype.tileSize = new google.maps.Size(256, 256); MarsMapType.prototype.getTile = function(coord, zoom, ownerDocument) { //The map is n by n tiles, where n == 2 ** zoom. var n = 1 << zoom; //Can't go above the north pole or below the south pole, var y = coord.y; if (y < 0 || y >= n) { return null; } //but can go round and round forever in the east/west direction. var x = coord.x % n; if (x < 0) { x += n; } var quadrant = new Array( new Array("q", "r"), new Array("t", "s") ); var img = ownerDocument.createElement("img"); img.src = "http://mw1.google.com/mw-planetary/mars/visible/t"; var x = coord.x; var y = coord.y; for (var n = 1 << zoom - 1; n > 0; n >>= 1) { img.src += quadrant[Math.floor(y / n)][Math.floor(x / n)]; x %= n; y %= n; } img.src += ".jpg"; return img; }; //This function is called by the webViewDidFinishLoad: method of the //UIWebViewDelegate. function mapFunction(latitude, longitude, zoom) { var options = { center: new google.maps.LatLng(latitude, longitude), mapTypeControl: false, scaleControl: true, zoom: zoom }; var map = new google.maps.Map(document.getElementById("map"), options); map.mapTypes.set("mars", new MarsMapType()); //add to map's registry map.setMapTypeId("mars"); } </script> </head> <body style = "height: 100%; margin: 0px; padding: 0px;"> <div id = "map" style = "width: 100%; height: 100%;"> </div> </body> </html>