32
Online Mapping with Google Maps API v3 Michael Peterson, Chair, International Cartographic Association Commission on Maps and the Internet University of Nebraska at Omaha

Online mapping with_the_google_maps_api

Embed Size (px)

Citation preview

Page 1: Online mapping with_the_google_maps_api

               

Online  Mapping  with  Google  Maps  API  v3            Michael  Peterson,  Chair,  International  Cartographic  Association  Commission  on  

Maps  and  the  Internet  University  of  Nebraska  at  Omaha  

Page 2: Online mapping with_the_google_maps_api

  2  

 

Introduction  

Introduced  in  2005,  Google  Maps  has  transformed  the  online  mapping.    No  longer  dependent  on   a   simple   and   slow   server-­‐client   relationship,   Google   Maps   uses   a   more   interactive,   tile-­‐based   system   based   on   AJAX   to   present   an   online   map   that   allows   for   highly   interactive  panning   and   zooming.    In   2006,   the   Google   Maps   Application   Programmer   Interface   was  introduced   that   facilitated   the   creation   of  Map  Mashups   –   the  mapping   of   data   from   online  sites.    Map  Mashups   have   had   a  major   impact   in   how   spatial   information   is   communicated.    This   workshop   examines   online   mapping   APIs   from   Google,   Bing   and   Yahoo.    Specific  examples   are  presented  using   the  Google  Maps  API   that   involves   the  mapping  of  point,   line,  and   area   data.    Both   in-­‐code   and   GeoRSS   data   will   be   mapped.   All   examples   use   an  HTML/JavaScript   interface   to   the   Google  Maps   API.    Some   familiarity   with   HTML   and   basic  programming  concepts  -­‐  objects,  arrays,  loops  -­‐  is  expected.    

After   a   short   overview,   the  workshop  will   be   conducted   in   a   hands-­‐on   fashion.    Participants  will   connect   to   the   Internet   using   their   own   laptops   and   download   a   zip   file  with   all   of   the  course   materials.    A   Windows   program   will   be   installed   to   edit   the   HTML/JavaScript   code.  Participants  will   need   to   have   the   access   privilege   on   their   own   laptop   to   install   programs.  Most  of   the  workshop  will   involve  understanding  how  various  Google  Maps  API  routines  are  called  and  how  they  are  used  to  make  customized  maps.  Participants  will  be  given  a  complete  hand-­‐out  and  all  necessary  coding  examples.  

 

Mashups  

Mashups  are  an  integral  part  of  what  is  commonly  referred  to  as  Web  2.0.  Introduced  in  2004,  Web   2.0   represents   a   variety   of   innovative   resources,   and   ways   of   interacting   with,   or  combining  web  content.   In  addition   to  mashups,  Web  2.0  also   includes   the  concept  of  wikis,  such   as   Wikipedia,   blog   pages,   podcasts,   RSS   feeds,   and   AJAX.   Social   networking   sites   like  MySpace  and  Facebook  are  also  seen  as  Web  2.0  applications.  

Central   to  mashups  are  Application  Programming  Interfaces  (APIs),  online   libraries  of  functions  that  are  made  available  at  no  cost  to  website  designers.  Many  different  API  libraries  have  been  written  for  the  user-­‐driven  web.  APIs  are  the  tools  that  facilitate  the  fusion  of  data  and   resources   from   multiple   web   resources   by   providing   tools   to   acquire,   manipulate   and  display  information  from  a  variety  of  sources.  In  a  strict  sense,  a  map  mashup  combines  data  from  one  website  and  displays   it  with  a  mapping  API.  The  term  has  come  to  be  used  for  any  mapping  of  data  using  an  API,  even  data  supplied  by  the  user.  It  should  not  be  surprising  that  maps  figure  prominently  as  mashups.  There  is  a  great  deal  of  data  presented  on  web  pages  that  has  a  locational  component.  The  relative  ease  of  overlaying  all  types  of  information  with  online  mapping  tools  has  further  transformed  cartography  from  a  passive  to  an  active  enterprise.  

Page 3: Online mapping with_the_google_maps_api

  3  

The   advantage   of   using   a   major   online   mapping   site   is   that   the   maps   represent   a  common   and   recognizable   representation   of   the  world.   Overlaying   features   on   top   of   these  maps   provides   a   frame   of   reference   for   the   map   user.   A   particular   advantage   for   thematic  mapping   is   the   ability   to   spatially   reference   thematic   data.   To   emphasize   patterns,   thematic  maps   have   limited   the   display   of   spatial   reference   data   such   as   the   location   of   cities   and  transportation  networks.  

This   chapter  demonstrates   the  use  of   the  Google  Maps  API,   the  most   commonly  used  API   for  mapping.  Other  APIs  exist   for  other  online  mapping,   including  those   from  Yahoo  and  Microsoft,  and  all  are  in  a  continual  state  of  development.  Most  APIs  are  designed  for  use  with  JavaScript.  Before  examining  mashup  procedures  with  Google  maps,  it  is  important  to  examine  programming  with  JavaScript  in  more  detail.  

JavaScript    

JavaScript,   introduced   briefly   in   the   last   chapter,   is   a   compact,   object-­‐based   language   for  developing  client-­‐side  applications.  It  is  not  a  computer  language  that  makes  executable  code,  like  C++  or  Java.  Rather,  the  browser  interprets  JavaScript  statements  that  are  embedded  in,  or  referenced  from,  an  HTML  page.  The  JavaScript  program  is  executed  when  the  browser  page  is  opened.  This  was   initially  viewed  as  a  problem  because   it   slowed  down  the  execution  of   the  program.  Compiled  programs  execute  more  quickly.  Computers  are  becoming  faster  so  there  is  no  longer  a  major  advantage  to  pre-­‐compiling  computer  code.  

  From  a  commercial  standpoint,  the  major  disadvantage  of  JavaScript  is  that  the  code  is  open  and  readable.  Anyone  can  view   the   JavaScript   code  by  simply  choosing  Page  Source  or  View  Source  from  the  browser.  This,  combined  with  the  lack  of  a  debugging  program  and  slow  processing  speeds,  has  limited  the  acceptance  of  the  language,  although  most  major  websites  use  some  form  of  JavaScript.  The  language  is  ideal  for  educational  purposes  because  the  code  is  freely  accessible  and  functions  can  be  easily  integrated.  

The   example   in   Figure   1   defines   a   simple   function   in   the   HEAD   section   of   an   HTML  document.  The  function  is  then  called  in  the  BODY  of  the  document.  The  function  square  takes  one  argument,  called  number,  and  the  function  consists  of  one  statement:    

return number * number  

that  indicates  it  should  return  the  argument  of  the  function  multiplied  by  itself.  The  return  statement  specifies  the  value  that  is  returned  by  the  function.    

Code Result

<HEAD> <SCRIPT LANGUAGE="JavaScript"> function square(number) { return number * number } </SCRIPT>

 

The  function  returned  25.    

Page 4: Online mapping with_the_google_maps_api

  4  

</HEAD> <BODY> <SCRIPT> document.write("The function returned ", square(5), ".") </SCRIPT> <P> All done. </BODY>

All done.

Figure 1. This function squares the number passed to it by a call to the function.

Rather  than  embedding  the  JavaScript  in  the  HTML  file,  either  in  the  BODY  or  the  HEAD,  it   is  possible  to  place  the  JavaScript   functions  within  a  separate   file.  The  SRC  attribute  of   the  <SCRIPT>   tag   specifies   the   external   file   where   the   JavaScript   code   can   be   found.   Figure   2  shows  the  external   file  called  7-­‐4common.js  and  how  it   is  referenced   in  the  HEAD  part  of  an  HTML   document.   The   external   JavaScript   file   may   contain   multiple   functions   but   no   HTML  code.    

function square(number) { return number * number } <HEAD> <TITLE>Referencing a file of functions</TITLE> <SCRIPT SRC="7-4common.js"> </SCRIPT> </HEAD> <BODY> <SCRIPT> document.write("The function returned ", square(5), ".") </SCRIPT> <P> All done. </BODY>

Figure 2. A function is placed into an external document, 7-4common.js. The function is then referenced from the HTML file with <SCRIPT SRC=”7.4common.js”>.

 

 

Objects  Objects  are  combinations  of  functions  and  data  all  packaged  under  a  single  name.  Each  object  has  properties,  methods,  and  event  handlers.  An  object  named  car,  for  example,  would  possess  properties   such   as   make,   model,   year,   and   color.   Methods  might   be   attributes   like   ‘go’   and  ‘stop’.  An  event  handler  includes  pressing  a  button  or  moving  the  mouse  over  a  link.  JavaScript  incorporates  several  built-­‐in  objects.  Figure  3  demonstrates  the  use  of  the  date  object.  

Page 5: Online mapping with_the_google_maps_api

  5  

Code Result  

<html> <script type="text/javascript"> function Time() { var currentTime = new Date() var hours = currentTime.getHours() var minutes = currentTime.getMinutes() var seconds = currentTime.getSeconds() // call the AddZero function to add a zero in front of numbers that are less than 10 hours = AddZero(hours) minutes = AddZero(minutes) seconds = AddZero(seconds) // write out the time document.write("<b>" + hours + " hours " + minutes + " minutes " + seconds + " seconds </b>") } function AddZero(i) { if (i<10) {i="0" + i} return i } </script> </head> // call the Time function <body onload="Time()"> </body> </html>  

 

19  hours  23  minutes  06  seconds

 

Figure 3. Calling the built-in Date object to determine the current time.

 

Calculations  JavaScript   includes   a   number   of   internal   functions   called   Math   Objects.   Most   of   these   are  trigonometric  functions  that  might  be  used  to  determine  the  distance  between  two  points  on  the   surface   of   the   earth,   as   in   Figure   4.   Other   functions   compute   numbers   like   the   absolute  value  or  square  root.    

<script type="text/javascript"> /*

Page 6: Online mapping with_the_google_maps_api

  6  

* Use Haversine formula to Calculate distance (in km) between two points specified by * latitude/longitude (in numeric degrees) LatLon.distHaversine = function(lat1, lon1, lat2, lon2) { var R = 6371; // earth's mean radius in km var dLat = (lat2-lat1).toRad(); var dLon = (lon2-lon1).toRad(); lat1 = lat1.toRad(), lat2 = lat2.toRad(); var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon/2) * Math.sin(dLon/2); var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); var d = R * c; return d; }

Figure 4. This function calculates the distance between the two locations.

Google  Maps  Like   other   online   interactive  mapping   sites,   Google   displays  maps   at  multiple   scales.   These  maps  are  in  raster  form  and  have  been  pre-­‐made  from  an  underlying  vector  database.  Google  offers   18  maps   of   the  world   at   different   scales   varying   from   approximately   1:85  million   to  1:4,800   at   the   equator.   Each   of   these   maps   has   been   tiled   into   individual   squares   that   are  downloaded   separately,   often   from   different   servers.   A   typical   Google  Map  might   download  map  tiles  from  seven  or  eight  different  IP  addresses,  each  associated  with  a  different  computer  that  could  be  located  at  different  Google  data  centers.  A  variety  of  AJAX  methods  are  used  to  update  the  map.  

  The   satellite   view   provided   by   Google   is   pieced   together   from   different   satellite  imagery.  In  most  cases,  urban  areas  are  shown  with  higher  resolution  data.  Security  concerns  have   led   to   some   imagery   being   intentionally   obscured   or   pixelated,   such   as   with   nuclear  power  plants  in  the  United  States  (see,  for  example,  Seabrook  Station  Nuclear  Power  Plant,  in  New  Hampshire).  The  power  plants  are  still  visible  but  at  a  reduced  resolution  with  obvious  pixelation.  

  Maps  and   imagery   in  Google  Maps  have  been  projected  with   the  Mercator  projection.  The  attributes  and  limitations  of  this  projection  have  been  well-­‐documented,  and  its  distorted  depiction   of   the   world   has   been   a   major   cause   for   concern   among   cartographers   and  geographers.  Although  the  projection  preserves  angles  and  can  be  used  with  a  compass  over  small   areas,   it   badly   distorts   area   –   particularly   at   extremes   in   latitude.   Greenland   is  represented  as  being  larger  than  Africa  when  in  fact  Africa  is  14  times  larger  than  Greenland.  Scale  varies  continuously  from  the  equator  to  the  polar  areas.  Changes  in  scale  can  be  observed  in   the  Google  Map  display  by   examining   the   scale  bar   for  medium  scale  maps  when  moving  north  or  south  away  from  the  equator.  This  change   in  map  scale   is  particularly  noticeable  at  the   extreme   latitudes.   Mathematically   speaking,   the   north   and   south   pole   in   the   Mercator  

Page 7: Online mapping with_the_google_maps_api

  7  

projection  are  at  infinity.  Therefore,  Google  Maps,  along  with  many  other  online  maps  that  use  the  Mercator  projection,  do  not  show  either  pole.  

Google  Maps  API  The  Google  Map  API  consists  of  a  series  of  map-­‐related  functions  that  may  be  invoked  by  the  user.  These  functions  control  the  appearance  of  the  map,  including  the  scale,  position,  and  any  added   information   in   the   form  of  points,   lines  or  areas.  The  purpose  of   the  API   is   to  make   it  possible   to   incorporate   Google  Maps   on  websites,   and   to   overlay   information   from   another  source.  

Basic  Google  Map  The   example   in   Figure  5   shows   the  Google  Map   and   JavaScript   code   for   displaying   a   simple  map  centered  at  a  specific  latitude  and  longitude.  The  zoom  level,  which  ranges  from  0  to  17,  is  set  to  15.  The  example  in  Figure  5,  adds  both  the  vertical  zoom  slider  in  the  upper-­‐left  corner  and   the   map   type   control   buttons   in   the   upper-­‐right   corner.   Scroll   button   zooming   is   also  enabled  and  the  map  is  displayed  in  hybrid  form  with  a  background  satellite  image.  

Determining   the   latitude/longitude   can   be   done   in   at   least   four   different   ways.   With  Google  Maps,  zoom-­‐in  as  far  as  possible  to   increase  the  accuracy  of  the  point  and  then  right-­‐mouse   click   (control-­‐click   with   a   Mac)   on   the   point   of   interest   and   select   “Directions   from  here”  or   “Directions   to  here”   from  the  pop-­‐up  menu.  The   latitude  and   longitude  of   the  point  will  appear  in  the  Start  Address  or  End  Address  form  at  the  top  of  the  page.  This  will  only  work  if   the   point   is   not   positioned   on   a   street.   The   latitude   /   longitude   for   a   point   may   also   be  determined   using   Google   Earth,   a   separate   program   available   from   Google.   To   display   the  coordinates   in   the  decimal   degrees   format   required   for  Google  Maps,   select  Tools   /  Options  and  click  on  the  decimal  degrees  option.  A  utility  called  LatLongGrabber  is  available  in  the  code  examples.   This   utility   returns   latitude   and   longitude   values   for   points   clicked.     The   fourth  approach  involves  activating  a  Google  Labs  feature  that  displays  these  values  in  a  tooltip.  

<!DOCTYPE html> <html>

<head> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <style type="text/css">

html { height: 100% } body { height: 100%; margin: 0px; padding: 0px } #map_canvas { height: 100% }

</style> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"> </script> <script type="text/javascript">

function initialize() { var latlng = new google.maps.LatLng(41.258531,-96.012599); var myOptions = { zoom: 15, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP }; var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); }

</script> </head>

Page 8: Online mapping with_the_google_maps_api

  8  

<body onload="initialize()"> <div id="map_canvas" style="width:100%; height:100%"> </div>

</body> </html>

Figure 5. A basic Google map.

Point Maps Google  Maps  excels  at  showing  the  location  for  points  of  interest  (POI).  By  default,  this  point  is  symbolized   with   an   upside-­‐down   raindrop   symbol   (see   Figure   6)   but   a   large   number   of  alternative  symbols  are  available,  and  it  is  even  possible  to  design  your  own.  The  marker  may  also  be  made  clickable  so  that  text,  a  picture,  or  a  small  video  displays  within  bubble  near  the  symbol.   The   symbol  may   also   be   graduated,   increasing   in   size   to   show  quantitative   data   by  location.  

<html> <head>

<meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <style type="text/css">

html { height: 100% } body { height: 100%; margin: 0px; padding: 0px } #map_canvas { height: 100% }

</style> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"> </script> <script type="text/javascript">

function initialize() { var myLatlng = new google.maps.LatLng(41.258531,-96.012599); var myOptions = { zoom: 15, center: myLatlng, mapTypeId: google.maps.MapTypeId.HYBRID } var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); var myLatLng = new google.maps.LatLng(41.258531,-96.012599); var beachMarker = new google.maps.Marker({ position: myLatLng, map: map, }); }

</script> </head> <body onload="initialize()">

<div id="map_canvas" style="width:600px; height:300px"> </div>

</body> </html>

Page 9: Online mapping with_the_google_maps_api

  9  

 

 

Figure 6. A single marker on a Google Hybrid map.

Page 10: Online mapping with_the_google_maps_api

  10  

Clickable Markers

All   of   the   markers   defined   to   this   point   have   been   passive   –   they   do   not   respond   to   user  actions.  The   advantage  of   a   clickable  marker   is   that   they   can  provide   information   about   the  marker.   In   the   example   in   Figure   7,   html   formatted   text   is   associated  with   a   variable   called  “html”.  The  GEvent.addListener  then  ties  this  text  to  the  marker.  When  the  user  clicks  on  the  marker,  the  text  is  displayed  in  a  pop-­‐up  bubble.  To  describe  each  marker  on  the  map,  an  array  of  text  strings  could  be  defined  and  associated  with  every  location.  

function initialize() { var myLatlng = new google.maps.LatLng(41.258531,-96.012599); var myOptions = { zoom: 9, center: myLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP } var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); var contentString = 'Durham Science Center<br />University of Nebraska at Omaha<br />Cartography and GIS Laboratory' var infowindow = new google.maps.InfoWindow({ content: contentString }); var marker = new google.maps.Marker({ position: myLatlng, map: map, title:"Omaha" }); google.maps.event.addListener(marker, 'click', function() { infowindow.open(map,marker); }); }

Figure 7. Example of a clickable marker. The contentString text variable is defined with HTML formatted text.

Page 11: Online mapping with_the_google_maps_api

  11  

Mapping Random Points The   example   in   Figure   8   computes   the   location   and   maps   five   random   points   using   the  JavaScript  random  number  function  Math.random.  This  function  returns  values  between  0  and  1.  Multiplying   the   result   of   the   random  number   generator   times   the   difference   between   the  longitude  values  (longspan)  and   latitude  (latspan)values,  respectively,  and  adding  this   to   the  current  corner  latitude  and  longitude  values  gives  the  location  of  the  random  point.

<script type="text/javascript">

var map; function initialize() { var myLatlng = new google.maps.LatLng(41.258531,-96.012599); var myOptions = { zoom: 18, center: myLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP } map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); // Add 5 markers to the map at random locations var southWest = new google.maps.LatLng(41.152446,-96.252708); var northEast = new google.maps.LatLng(41.36150, -95.8579); var bounds = new google.maps.LatLngBounds(southWest,northEast); map.fitBounds(bounds); var lngSpan = northEast.lng() - southWest.lng(); var latSpan = northEast.lat() - southWest.lat(); for (var i = 0; i 5; i++) { var location = new google.maps.LatLng(southWest.lat() + latSpan * Math.random(), southWest.lng() + lngSpan * Math.random()); var marker = new google.maps.Marker({ position: location, map: map }); var j = i + 1; marker.setTitle(j.toString()); attachMessage(marker, i); } } // The five markers show the number of the marker when clicked function attachMessage(marker, number) { var message = ["Marker One","Marker Two","Marker Three","Marker Four","Marker Five"]; var infowindow = new google.maps.InfoWindow( { content: message[number], size: new google.maps.Size(50,50) }); google.maps.event.addListener(marker, 'click', function() { infowindow.open(map,marker); }); }

</script>

Page 12: Online mapping with_the_google_maps_api

  12  

Figure 8. Randomly positioned markers.

Page 13: Online mapping with_the_google_maps_api

  13  

Mapping Points from an xml file If  more  than  one  point  is  to  be  mapped,  it  would  be  good  to  store  the  points  in  an  external  file.  In  the  example  in  Figure  9,  the  file  is  formatted  in  xml  and  read  using  the  downloadUrl  function  that  is  located  in  an  external  .js  file.  In  this  case,  example.xml  contains  three  points  defined  as  latitude/longitude  with  bubble  text  formatted  in  html  and  a  tooltip  label  that  appears  when  the  mouse  is  positioned  over  the  point.  

function initialize() { // create the map var myOptions = { zoom: 8, center: new google.maps.LatLng(43.907787,-79.359741), mapTypeControl: true, mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU}, navigationControl: true, mapTypeId: google.maps.MapTypeId.ROADMAP } map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); google.maps.event.addListener(map, 'click', function() { infowindow.close(); }); // Read the data from example.xml downloadUrl("example.xml", function(doc) { var xmlDoc = xmlParse(doc); var markers = xmlDoc.documentElement.getElementsByTagName("marker"); for (var i = 0; i markers.length; i++) { // obtain the attribues of each marker var lat = parseFloat(markers[i].getAttribute("lat")); var lng = parseFloat(markers[i].getAttribute("lng")); var point = new google.maps.LatLng(lat,lng); var html = markers[i].getAttribute("html"); var label = markers[i].getAttribute("label"); // create the marker var marker = createMarker(point,label,html); } // put the assembled side_bar_html contents into the side_bar div document.getElementById("side_bar").innerHTML = side_bar_html; }); }  

example.xml <markers>

<marker lat="43.65654" lng="-79.90138" html="Some stuff to display in the&lt;br&gt;First Info Window" label="Marker One"> </marker> <marker lat="43.91892" lng="-78.89231" html="Some stuff to display in the&lt;br&gt;Second Info Window" label="Marker Two"> </marker> <marker lat="43.82589" lng="-79.10040" html="Some stuff to display in the&lt;br&gt;Third Info Window" label="Marker Three"> </marker>

</markers>

Page 14: Online mapping with_the_google_maps_api

  14  

Figure 9. Displaying multiple markers with a sidebar. The position for each marker along with the associated bubble text and tooltip text is defined in an xml file.

Page 15: Online mapping with_the_google_maps_api

  15  

Mapping Points through RSS from a KML file RSS  is  a  web  format  used  to  publish  frequently  updated  data  such  as  news  and  other  types  of  frequently  updated  information.  RSS  feeds  include  content  and    metadata  such  as  the  date  and  author.  Publishers  benefit  by   syndicating   content  automatically.     Consumers  benefit   through  timely  updates  from  favored  websites.  A  standardized  XML  file  format  allows  the  information  to  be  published  once  and  viewed  by  many  different  programs.  

KML,   Keyhole   Markup   Language,   is   an   XML   based   format   for   describing   two-­‐   and   three-­‐dimensional  space.  The  format  specifies  features  such  as  places  marks,  images,  polygons,  and  3D  models.  Places  are  always  specified  with   latitude  and   longitude.  Some  KML   features  may  not  be  viewable  with  Google  Maps.  

The  google.maps.KmlLayer function  reads  a  KML-­‐formatted  RSS   feed   (see  Figure  10).  The   feed   is  specified  with  an  http  address.    The  address  used  in  this  example  comes  from  flickr,  an  image  hosting  website.     In   this  case,  a  user  has  geocoded  a  series  of  photos  and  has  made   the   feed  available   for  syndication.  RSS   is  an  efficient   form  of  data  distribution  and  maps  made   in   this  way  are  usually  displayed  faster  than  if  read  from  an  XML  file,  as  in  the  example  above.  

<script type="text/javascript">

function initialize() { var myLatlng = new google.maps.LatLng(49.496675,-102.65625); var myOptions = { zoom: 4, center: myLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP } var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); var georssLayer = new google.maps.KmlLayer('http://api.flickr.com/services/feeds/geo/?g=322338@N20&lang=en-us&format=feed-georss'); georssLayer.setMap(map); }

</script>  

Figure 10. Displaying a RSS feed defined in KML format from the flickr website.

Page 16: Online mapping with_the_google_maps_api

  16  

Mapping RSS Points with Layer Side Info The  example  in  Figure  11  reads  an  RSS  file  from  Searcharoo.net,  a  site  that  provides  an  open-­‐source  C#/ACP.NET  implementation  of  a  search  engine  that  you  can  download  and  use  on  your  website.   The   “newyork.kml”   that   they   make   available   is   a   result   of   a   search   for   geocoded  information,   including  a  picture.    A  part  of   the  KML   file   is   shown   in  Figure  10.  Clicking  on  a  map  maker  displays  this  information  in  a  sidebar  div  layer  on  the  side  of  the  map.  

<script type="text/javascript">

function initialize() { var myLatlng = new google.maps.LatLng(40.65, -73.95); var myOptions = { zoom: 12, center: myLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP }; var map = new google.maps.Map( document.getElementById("map_canvas"), myOptions); var nyLayer = new google.maps.KmlLayer( 'http://www.searcharoo.net/SearchKml/newyork.kml', { suppressInfoWindows: true, map: map}); google.maps.event.addListener(nyLayer, 'click', function(kmlEvent) { var text = kmlEvent.featureData.description; showInContentWindow(text); }); function showInContentWindow(text) { var sidediv = document.getElementById('content_window'); sidediv.innerHTML = text; } }

</script> </head> <body onLoad="initialize()">

<div id="map_canvas" style="width:79%; height:100%; float:left"> </div> <div id="content_window" style="width:19%; height:100%; float:left"> </div> </body>  

KML  File   <?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://www.opengis.net/kml/2.2">

<Document> <Placemark>

<description> <![CDATA[ Cable ties on Brooklyn Bridge <b>newyork </b>brooklyn brooklynbridge <br /> <a href="http://searcharoo.net/searcharoov6/testfiles/brooklynbridge%20(perspective).jpg">

<img src="http://searcharoo.net/searcharoov6/testfiles/brooklynbridge%20(perspective).jpg" width="120" />

</a> <br /> Tags: newyork, brooklyn, brooklynbridge, , manhattan <br /> Size: 121975 <br /> Crawled Date: 3/6/2009 3:31:58 AM <br /> Rank: (1) ]]>

</description> <Style>

<IconStyle> <Icon>

Page 17: Online mapping with_the_google_maps_api

  17  

<href> http://searcharoo.net/searcharoov6/testfiles/brooklynbridge%20(perspective).jpg

</href> </Icon>

</IconStyle> </Style> <Point>

<extrude> 1

</extrude> <altitudeMode>

relativeToGround </altitudeMode> <coordinates>

-73.9955001666667,40.7050708333333,0 </coordinates>

</Point> </Placemark>

Figure 11. Displaying a RSS feed defined in KML format from the flickr website.

Page 18: Online mapping with_the_google_maps_api

  18  

Mapping data from Fusion tables Fusion  Tables  is  a  free  Google  service  for  storing  and  managing  tabular  data  in  the  cloud.  Data  sets   up   to   100MB   can   be   uploaded   and   shared   with   collaborators   or   made   public.   Once  uploaded,  data  may  be  filtered,  aggregated,  merged,  and  exported  in  multiple  formats.  It  is  also  possible  to  display  the  data  in  charts  and  maps.  Part  of  a  Fusion  Table  of  crime  in  Chicago  is  shown   in   Figure   12.     This   data   is   accessed   with   the   Google   Maps   API   using   the  google.maps.FusionTablesLayer(139529) function,  where  139529  is  the  name  of  the  Fusion  Table.    

Fusion  Tables  are  managed  through  the  Google  Fusion  Tables  API.  This  API  makes  it  possible  to  upload  data  by  row,  from  a  single  row  to  hundreds  at  a  time.  Functions  are  available  for  data  querry   based   on   a   subset   of   the   SQL   querrying   language.   Finally,   a   Fusion   Table   may   be  synchronized  with  an  offline  respository.  

 

<html> <head>

<meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <style type="text/css">

html { height: 100% } body { height: 100%; margin: 0px; padding: 0px } #map_canvas { height: 100% }

</style> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"> </script> <script type="text/javascript">

function initialize() { var chicago = new google.maps.LatLng(41.850033, -87.6500523); map = new google.maps.Map(document.getElementById('map_canvas'), { center: chicago, zoom: 10, mapTypeId: 'roadmap' }); // View this table in a webpage: http://tables.googlelabs.com/DataSource?dsrcid=139529 layer = new google.maps.FusionTablesLayer(139529); layer.setMap(map); }

</script> </head> <body onload="initialize()">

<div id="map_canvas" style="width:600px; height:300px; float:left"> </div>

</body> </html>  

Page 19: Online mapping with_the_google_maps_api

  19  

 

Figure 12. Displaying a RSS feed defined in KML format from the flickr website.

Page 20: Online mapping with_the_google_maps_api

  20  

Marker based on Street Address One  of   the  most  powerful   functions  of  Google  Maps   is   the  geocoding  of  addresses.  Figure  13  shows  how  a  single  address  is  geocoded  using  the  geocoder.geocode  function.  This  location  is  then  shown  with  a  marker  on  the  map.    

<script type="text/javascript"> var geocoder; var map; function initialize() { geocoder = new google.maps.Geocoder(); var latlng = new google.maps.LatLng(41.258531,-96.012599); var myOptions = { zoom: 13, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP } map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); } function codeAddress() { var address = document.getElementById("address").value; geocoder.geocode( { 'address': address}, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { map.setCenter(results[0].geometry.location); var marker = new google.maps.Marker({ map: map, position: results[0].geometry.location }); } else { alert("Geocode was not successful for the following reason: " + status); } }); }

</script> </head> <body onload="initialize()">

<div> <input id="address" type="textbox" value="6001 Dodge, Omaha, NE" /> <input type="button" value="Geocode" onclick="codeAddress()" />

</div> <div id="map_canvas" style="height:90%"> </div>

</body>  

Figure 13. Placing a marker based on a street address.

Page 21: Online mapping with_the_google_maps_api

  21  

Custom Markers Markers  are  small  graphic  files  defined  in  the  PNG  graphic  file  format  that  are  normally  32x32  pixels,  but  can  be  of  any  size.  A  large  number  of  different  icons  are  available  that  can  be  used  to  denote   the   location   of   almost   any   type   of   feature,   including   icons   for   restaurants,   airports,  bathrooms,  etc.  (see  Figure  14).  A  shadow  is  usually  also  associated  with  the  icon  to  provide  a  3-­‐D   appearance,   as   shown  with   the   restaurant   symbol   at   the   bottom   of   Figure   9.   Icons   are  designed  using  a  pixel-­‐based  graphic  editing  program  such  as  Adobe  Photoshop.  

Figure 14. Alternative Google Maps point symbols.

Graduated Symbols Graduated  symbols  are  used  to  depict  the  magnitude  of  a  variable  at  a  point.  The  symbols  are  made  progressively   larger   to  show  increases   in  quantity,  such  as  population.  The  size  of  any  type  of  symbol  can  be  varied,  but  usually  geometric  shapes  are  used  like  circles  or  squares.  

There  are  a  variety  of  ways  to  create  symbols  of  varying  sizes  with  Google  Maps.  One  way  would  be  to  define  a  series  of  icons  with  different  sizes.  Ten  icons  could  be  defined  from  a  small   4x4   grid   to   a   size   of   256x256   pixels   or  more.   The   data   to   be  mapped  would   then   be  classified  into  ten  categories  and  assigned  to  one  of  the  symbols  sizes.  

  An   alternative  method   is   to   draw   the   symbol   at   a   specified   size,   as  with   the   circle   in  Figure   15.   Here,   a   google.maps.Circle   function   is   called   with   a   radius   of   3000   KM.   Multiple  circles  could  be  drawn  at  different  locations  to  represent  a  distribution  such  as  the  population  of   cities,   and   the   circles   could   be  made   proportional   to   population.   It   has   been   shown   that  circle   sizes   are   perceptually   underestimated   requiring   the   map   maker   to   compensate   by  adjusting  the  size  of  the  circles  upward  with  an  exponent.

Page 22: Online mapping with_the_google_maps_api

  22  

<html> <head>

<meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>

Circle Overlay </title> <style type="text/css">

#map { width: 800px; height: 500px; }

</style> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"> </script> <script type="text/javascript">

/** * Called on the initial page load. */ function init() { var mapCenter = new google.maps.LatLng(0, 0); var map = new google.maps.Map(document.getElementById('map'), { 'zoom': 1, 'center': mapCenter, 'mapTypeId': google.maps.MapTypeId.ROADMAP }); // Create a draggable marker which will later on be binded to a // Circle overlay. var marker = new google.maps.Marker({ map: map, position: new google.maps.LatLng(35, 0), draggable: true, title: 'Drag me!' }); // Add a Circle overlay to the map. var circle = new google.maps.Circle({ map: map, radius: 3000000; // 3000 km

fillColor: "#3da5e1", fillOpacity: 0.5, strokeColor: "#2b546b", strokeWeight: 1

}); // Since Circle and Marker both extend MVCObject, you can bind them // together using MVCObject's bindTo() method. Here, we're binding // the Circle's center to the Marker's position. // http://code.google.com/apis/maps/documentation/v3/reference.html#MVCObject circle.bindTo('center', marker, 'position'); } // Register an event listener to fire when the page finishes loading. google.maps.event.addDomListener(window, 'load', init);

</script> </head> <body>

<h1> Drag the marker to move the circle

</h1> <div id="map"> </div>

</body> </html>    

Page 23: Online mapping with_the_google_maps_api

  23  

Figure 15. Draggable circle drawn on a world map. Defined with a radius of 3000 KM, the circle changes shape because of the use of the Mercator projection.

Page 24: Online mapping with_the_google_maps_api

  24  

Line Maps The  google.maps.Polyline   is  used   to  draw   lines  with  Google  Maps.   In  Figure  16,   the  PolyLine  function   is   used   to   connect   points   input   by   the   user.   Options   include   strokeColor,  strokeOpacity,  and  strokeWeight.  

<script type="text/javascript"> var poly; var map; function initialize() { var omaha = new google.maps.LatLng(41.258531,-96.012599); var myOptions = { zoom: 9, center: omaha, mapTypeId: google.maps.MapTypeId.ROADMAP }; map = new google.maps.Map(document.getElementById('map_canvas'), myOptions); var polyOptions = { strokeColor: '#000000', strokeOpacity: 1.0, strokeWeight: 3 } poly = new google.maps.Polyline(polyOptions); poly.setMap(map); // Add a listener for the click event google.maps.event.addListener(map, 'click', addLatLng); } /** * Handles click events on a map, and adds a new point to the Polyline. * @param {MouseEvent} mouseEvent */ function addLatLng(event) { var path = poly.getPath(); // Because path is an MVCArray, we can simply append a new coordinate // and it will automatically appear path.push(event.latLng); // Add a new marker at the new plotted point on the polyline. var marker = new google.maps.Marker({ position: event.latLng, title: '#' + path.getLength(), map: map }); }

</script>  

Page 25: Online mapping with_the_google_maps_api

  25  

Figure 16. The polyLine function is used to draw lines on the map to connect points input by the user.

Page 26: Online mapping with_the_google_maps_api

  26  

Area Maps The   final   symbol   type   to  be  examined  here   is   the  area   symbol,  used   to  make   the  choropleth  map.   The   choropleth  method   uses   shadings   to   indicate   the   quality   or   value   over   an   area.   A  qualitative  choropleth  map  would  indicate  nominal  differences  like  zoning  areas,  or  soil  types.  A  quantitative  choropleth  map  would  display  differences  in  the  quantity  of  a  variable  as  with  a  map  that  shows  the  percent  of  votes  received  by  a  candidate  by  election  precincts.  Quantitative  choropleth  maps  are  by  far  the  most  common  of  the  two  types.

  The  making  of  a  choropleth  map  with  Google  Maps  would  involve  the  use  of  the  Polygon  function  (see  Figure  17).  The  function  is  essentially  identical  to  Polyline  except  that  a  fill  color  and   opacity   is   also   defined.   As   with   the   Polyline,   the   function   is   provided   an   array   of  coordinates  that  outline  the  area.  But,  with  Polygon,  the  first  and  last  points  are  identical,  thus  closing  the  polygon.    

<script type="text/javascript"> function initialize() { var myLatLng = new google.maps.LatLng(24.886436490787712, -70.2685546875); var myOptions = { zoom: 5, center: myLatLng, mapTypeId: google.maps.MapTypeId.TERRAIN }; var bermudaTriangle; var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); var triangleCoords = [ new google.maps.LatLng(25.774252, -80.190262), new google.maps.LatLng(18.466465, -66.118292), new google.maps.LatLng(32.321384, -64.75737), new google.maps.LatLng(25.774252, -80.190262) ]; // Construct the polygon bermudaTriangle = new google.maps.Polygon({ paths: triangleCoords, strokeColor: "#FF0000", strokeOpacity: 0.8, strokeWeight: 2, fillColor: "#FF0000", fillOpacity: 0.35 }); bermudaTriangle.setMap(map); }

</script>  

Page 27: Online mapping with_the_google_maps_api

  27  

Figure 17. The Google Polygon function is used to draw a polygon. Options include strokeColor, strokeOpacity, strokeWeight, fillColor and fillOpacity.

Page 28: Online mapping with_the_google_maps_api

  28  

Heat Maps The  so-­‐called  heat  map  is  a  product  of  the  mashup  era.  It  is  essentially  a  density  map  where  a  higher  density  of  points  is  given  a  red  color.    As  the  density  declines,  the  color  changes  to  orange  and  red.  Figure  18  shows  a  density  map  of  beaches  in  Brazil.  Data  is  provided  through  a  Fusion  Table.

</script> <script type="text/javascript">

function initialize() { var brazil = new google.maps.LatLng(-18.771115, -42.758789); map = new google.maps.Map(document.getElementById('map_canvas'), { center: brazil, zoom: 4, mapTypeId: 'roadmap' }); // Table 136705 has beaches along Brazil's coastline // View this table in a webpage: http://tables.googlelabs.com/DataSource?dsrcid=136705 layer = new google.maps.FusionTablesLayer(136705, { heatmap: true }); layer.setMap(map); } </script>  

Page 29: Online mapping with_the_google_maps_api

  29  

Figure 18. A “Heatmap” generated from the density of points defined in a Fusion Table.

 

 

Yahoo Maps and Bing Maps Competing  with  MapQuest,  Yahoo!  provided  an  online  mapping  service  that  used  the  older  client/server  model.  The  server  responded  with  a  user-­‐requested  map  that  was  embedded  within  a  web  page.    Soon  after  the  introduction  of  Google  Maps  in  2005,  Yahoo  changed  it’s  online  mapping  service  to  incorporate  an  AJAX-­‐type  interface  that  worked  with  Flash.    By  2006,  Yahoo!  had  released  its  own  API.  The  Yahoo!  Maps  API  is  much  the  same  as  Google’s  implementation  but  does  not  support  polygons  and  requires  the  use  of  an  electronic  key.    

In  mid-­‐2009,  Microsoft  re-­‐labeled  its  Live  Local  web  mapping  service  to  Bing  Maps,  a  part  of  the  companies  search  engine  services.  Bing  Maps  includes  a  street  map,  an  aerial  view,  Bird’s-­‐Eye  view,  StreetSide  view,  and  3D  Maps.    The  oblique  Bird’s  Eye  view  has  more  detail  than  Google’s  satellite  view.  In  contrast  to  the  Yahoo!  Maps  API,  Bing  Maps  does  support  polygons.  

Figure  19  compares  the  code  between  Yahoo!  and  Bing  maps.    

Page 30: Online mapping with_the_google_maps_api

  30  

Figure 19. Example of code for Yahoo! Maps API and Bing Maps API.

Page 31: Online mapping with_the_google_maps_api

  31  

Mapstraction  

Mapstraction  is  an  open-­‐source  library  that  provides  a  common  API  for  various  JavaScript  mapping  APIs.  The  purpose  is  to  make  it  possible  to  easily  switch  between  the  different  APIs  without  having  to  worry  about  the  unique  implementation.  The  example  in  Figure  20  shows  a  Mapstraction  implementation  that  creates  a  map  with  six  different  mapping  APIs.  

 

<html> <head>

<script src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAAKRwVKGgdK08PzFOkI4mzwBSxwhHJj4F5mVjLsNT2AfMLlpoynxTk5g96WAoVkzIABODCjMST2qhLwg" type="text/javascript"> </script> <script type="text/javascript" src="http://api.maps.yahoo.com/ajaxymap?v=3.0&appid=MapstractionDemo"> </script> <script src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6"> </script> <script type="text/javascript" src="http://developer.multimap.com/API/maps/1.2/OA070606486554191"> </script> <script src="http://btilelog.beta.mapquest.com/tilelog/transaction?transaction=script&key=mjtd%7Clu6t210anh%2Crn%3Do5-labwu&itk=true&v=5.3.0_RC5&ipkg=controls1" type="text/javascript"> </script> <script type="text/javascript" src="mapstraction-js/mapstraction.js"> </script> <style type="text/css">

.mapstraction { height: 100%; width: 100%; z-index: 1; } #map_select { bottom:40px; left:25px; position:absolute; background-color:white; padding: 5px; border:2px solid black; z-index: 1000; }

</style> </head> <body>

<div id="google" class="mapstraction"> </div> <div id="multimap" class="mapstraction" style="display:none"></div> <div id="yahoo" class="mapstraction" style="display:none"></div> <div id="microsoft" class="mapstraction" style="display:none"></div> <div id="freearth" class="mapstraction" style="display:none"></div> <div id="mapquest" class="mapstraction" style="display:none"></div> <div id="openstreetmap" class="mapstraction" style="display:none"></div> <div id="mapquest" class="mapstraction" style="display:none;height: 100%; width: 100%;"></div> <script type="text/javascript">

// initialise the map with your choice of API var mapstraction = new Mapstraction('google','google'); // create a lat/lon object var myPoint = new LatLonPoint(38.8971, -77.070857); // display the map centered on a latitude and longitude (Google zoom levels) mapstraction.setCenterAndZoom(myPoint, 13); // create a marker positioned at a lat/lon my_marker = new Marker(myPoint); // add info bubble to the marker var text = "Rock it out at JSConf!"; my_marker.setInfoBubble(text);

Page 32: Online mapping with_the_google_maps_api

  32  

// display marker mapstraction.addMarker(my_marker);

</script> <div id="map_select">

<form action="get"> <input type="radio" name="api" value="google" CHECKED="1" onClick="mapstraction.swap('google','google')" /> Google<br /> <input type="radio" name="api" value="multimap" onClick="mapstraction.swap('multimap','multimap')" /> MultiMap<br /> <input type="radio" name="api" value="yahoo" onClick="mapstraction.swap('yahoo','yahoo')" /> Yahoo<br /> <input type="radio" name="api" value="microsoft" onClick="mapstraction.swap('microsoft','microsoft')" /> Microsoft<br /> <input type="radio" name="api" value="openstreetmap" onClick="mapstraction.swap('openstreetmap','openstreetmap')" /> OpenStreetMap<br /> <input type="radio" name="api" value="mapquest" onClick="mapstraction.swap('mapquest','mapquest')" /> MapQuest<br />

</form> </div>

</body> </html>

Figure 20. An implementation of Mapstraction, an open-source API that provides a common interface to multiple online mapping sites.