Saturday, 26 March 2011

Maps in articles

If you've got a page that contains significant information other than the map, then you won't want to deny access to people using browsers that are not compatible with the Google maps API or which have Javascript turned off. They might be interested to read the text in the rest of the page

What you can do is to remove the <noscript> section, and the alert that you'd normally throw for a non-compatible browser. Instead, initially create the map <div> with zero size, like this.
<div id="map" style="width: 0px; height: 0px"></div>
Then, in your Javascript, if the browser is compatible, change the width and height to the required size just before creating the GMap.
var m = document.getElementById("map");
m.style.height = "400px";
m.style.width = "500px";
var map = new GMap2(m);

Links and Images on Gmap

You can include links and images in your info windows, and use most HTML formatting commands, as long as you follow a few simple rules:
  • Use different types of quotes in the HTML from those that you use in Javascript
    Like this '<a href="http://sharafjaffri.blogspot.com">'
    or like this "<a href='http://sharafjaffri.blogspot.com'>"
  • When using images, do specify the height and width, otherwise the size of the info window will be calculated incorrectly.'<img src="test.jpg" width=150 height=100>'
  • If loading the information from XML, replace '<' and '>' characters with '&lt;' and '&gt;'.
    '&lt;img src="image.jpg" width=150 height=100&gt;'
  • If you want to try writing code that passes W3C Validation, then you need to avoid having the characters "</" in your text. The officially correct way to write "</a>" is to insert a backslash before the forward slash, like "<\/a>".

Loading Markers data from an XML file


XML
If you are going to use dozens of markers on your page, it will become difficult to manage them if you code them all in your Javascript as in the Described earlier. The preferred method for handling large numbers of markers is to store the data in an XML file. It's also possible to fetch data from database which returns XML containing a different selection from the data depending on query information derived from what your users input. I'm not going to cover this side of things in this tutorial.
The code used GDownloadUrl() to send a request to read the file.
Once the data has been read, the callback function can grab a collection of data from the XML tags
 var markers = xmlDoc.documentElement.getElementsByTagName("marker");
then for each of those tags extract the individual attribute fields
 var lat = parseFloat(markers[i].getAttribute("lat"));
Once all the data has been parsed, we can create the markers as in the previous examples.
XML attributes strings can't contain the characters < or >. You have to use &lt; and &gt;, which will get converted to < and > as the XML data is read.
Instead of using XML attributes, it's possible to lay out your XML data like this:
   <markers>
     <marker lat="67.65654" lng="24.90138" label="Marker One">
      <infowindow>Some stuff to display in the&lt;br&gt;First Info Window</infowindow>
     </marker>
   </markers>
Or even like this, using CDATA:
   <markers>
     <marker lat="67.65654" lng="24.90138" label="Marker One">
      <infowindow><![CDATA[
        Some stuff to display in the<br>First Info Window
      ]]></infowindow>
     </marker>
   </markers>
When using CDATA, is is not necessary to use &lt; and &gt; in the contained HTML.

XML formatted like this can be read with GXml.value, like this
   var html = GXml.value(markers[i].getElementsByTagName("infowindow")[0]);

Friday, 25 March 2011

Markers and info windows

Markers and info windows

Not all browsers support the Google API, and not all users run their browsers with Javascript enabled.
So use a <noscript> element to detect the situation where there is no Javascript, and use
GBrowserIsCompatible() to detect a non-compatible browser.

The createMarker() function not only sets up the marker and its event handler,
but it also causes local copies of the "marker" and "html" variables to be preserved for later use when the event gets triggered.
This is a special feature of the Javascript language called "function closure".

You can use almost any valid html in the info window, as long as the browser can work out the required height and width before rendering it.

If you want to use html that uses quotes, you can use single-quotes in the Javascript string and double-quotes in the contained html.

E.g. createMarker(point,'<image src="myimage.jpg" width=150 height=100>');

Potential Pitfalls

  1. The info window contents inherit the formatting from the parent document.
      E.g. if your map <div> is positioned with <center>, then the info window contents will be centred. 
  2.  The code that works out the size of the info window is executed before this style inheritance takes place. If your info window contents then inherit styles that change their size, for example font-size,
      then the info window size may not fit the contents very well.
  3. Don't attempt to "unroll" the createMarker() function. This doesn't work.
    var point = new GPoint(-79.90138, 43.65654);
          GEvent.addListener(marker, "click", function() {
            marker.openInfoWindowHtml("Some stuff");
          });
          map.addOverlay(marker);
    
          var point = new GPoint(-78.89231, 43.91892);
          GEvent.addListener(marker, "click", function() {
            marker.openInfoWindowHtml("Some other stuff");
          });
          map.addOverlay(marker);
          
    What goes wrong is that there's only one copy of the "marker" variable.
    When the "click" event gets triggered at a later time, it gets the value that's in the variable at the time of the call,
      but you want the value at the time the event handler was set up.
  4.  Don't put your Javascript inside a <table> or <div>, it will work in Firefox, but not in IE.  Safe places to put your Javascript are either just before the </body>, or in the header in an onLoad() function.
  5.  If you do use an onLoad() function, be careful not to call it "onload()" in all lower case, because that's a reserved word in Firefox.
  6.  If you put an image into an info window, you must specify the height and width, so that the browser can calculate the size of the info window before starting to render the image.
  7.  If you use tables or divs inside an info window, do specify the width and height. Don't use "width=100%", or the browser won't be able to calculate the size of the window before rendering the table.
  8.  Make sure that the id of your map div is unique.  Things get rather messy if you've got an image_map on your page which uses id="map", or an anchor that uses name="map".
  9. Do test your page in both IE and a browser that supports standards-compliant Javascript, such as Firefox.  If you follow this tutorial, then your code should work on both, but it's easy to miss something and end up with a map that only works in one environment.  If you want to be confident that your code works in all browsers, you don't really need to test hundreds of different browsers because most compliant browsers are built around a small number of layout engines. Just test MSIE6, MSIE7, plus
      one browser that uses each of the compatibayout engines:

    Engine Browsers
    Gecko Firefox, Camino, Mozilla, Netscape, etc.
    Presto Opera, Nintendo, plus forthcoming Adobe browsers
    WebKit Safari, Google Chrome, Arora, Midori, Omniweb, etc.


Embedded Maps

It's now easy to embed a maps.google.com map in your own web page. It can include map searches, get directions, My Maps, KML files and GeoRSS files. It can't include Mapplets as well.

The content is dynamic. The display shows the current result of performing the search or loading the My Map file. All you have to do is to go to maps.google.com and set up the view exactly how you want it, then click on "Link to this page" and copy the "Paste HTML to embed in website" text into your own web page. No API key is required. No knowledge of Javascript is required.There's a "Customise and preview" option that allows you to change the size of the embedded map.

Instant maps using Google Wizard

Google provides a Wizard which will generate a chunk of code that you can add to your own web page.

Example:
Maps generated by the Google map Wizard only show a single marker, and you don't get any control over the contents of the info window. The generated map will also have a Google AJAX Search API box, and direction finding (in a new maps.google.com window)
You don't even have to sign up for an API key. The Wizard creates its own key for your domain.

Restrictions

The Wizard only works for locations that can be found with the Google AJAX Search API.

How to use it
  • Go to the Wizard page and follow the three simple steps.
  • Copy and paste the generated code into your own web page.
  • Cut the code into two pieces. The bit that looks something like this can be placed anywhere on your page
    • <div id="mapsearch">
      <span style="color:#676767;font-size:11px;margin:10px;padding:4px;">Loading...</span>
       </div> 
  • The rest of the code should be placed just before the at the bottom of your page.
  • Double-click your page to test it, then upload it to your website.

Adding a google map to blogger

  1. Before you start you are required to get Google Maps API key freely available at http://maps.google.com/apis/maps/signup.html, and enter the url of your blog to get the key. eg for My blog http://usegmap.blogspot.com/
  2. You need to edit the template for your blog. (Warning: editing your template can lead to breaking your blog, it might be good to copy and paste your template into something like notepad before changing it).Just under the <head> tag, which should be near the top, add the line

    <script src="http://maps.google.com/maps?file=api&v=1&key=xxxx" type="text/javascript"></script>
    

    and replace xxxx with the key you received.

    Now its your turn to decide where on you blog to place map.insert the code:

    <div id="map" style="width: 100%; height: 300px"></div>
    


    Finally, add the following code just above the </body> tag in the template (should be near the bottom)
    <script type="text/javascript">
        //<![CDATA[
    
        function createMarker(x, y, title, thumbnail, image) {
          var point = new GPoint(x, y);
          var marker = new GMarker(point);
          var html = '<center>' + title + '<br /><a href="' + image + '" target="_blank"><img src="' + thumbnail + '" /></a><br /></center>';
    
          GEvent.addListener(marker, "click", function() {
            marker.openInfoWindowHtml(html);
          });
    
          map.addOverlay(marker);
        }
        
        var map = new GMap(document.getElementById("map"));
        map.addControl(new GLargeMapControl());
        mapTypes = map.getMapTypes();
        map.setMapType(mapTypes[1]);
    
    
        //  ** change this line to set the location of the map and the zoom level. ** //
        map.centerAndZoom(new GPoint(24.599310, 67.918413), 4);    
    
        
        // ** add createMarker function calls to create markers. ** //
        createMarker(24.60215306282, 67.920666217804, 'Test Link', 'http://www.test.com/test.jpg', 'http://www.test.com/1.jpg');
    
    
        //]]>
        </script>

    To change the location the map initially displays, edit the line:

    map.centerAndZoom(new GPoint(24.599310, 67.918413), 4);   
    
    

    To add markers to the map, add lines such as:

    createMarker(latitude, longitude, 'title', 'thumbnail url', 'image url');
    

    an example is:
    createMarker(24.60215306282, 67.920666217804, 'Test Marker', 'http://www.testtest.com/mapImages/t1.jpg', 'http://www.testtest.com/mapImages/1.jpg');