Wednesday, April 29, 2009

Google O3D - a new web standard for 3D graphics?

Since VRLM/X3D times there was no other interesting replacement for web 3D graphics. Unfortunately VRML/X3D was also not so widely used as it was expected. Perhaps it was to innovative for its times.

Around two weeks ago Google (in contribution with Khronos) released new JavaScript API for creating interactive 3D graphics applications that run directly in a browser window using a special plug-in. More information here.

At this moment there are only few configurations that are fully supported and my old hardware is not on this list. Just to get a taste of O3D I used my friend’s computer to create a simple example with o3djs.simple utility library.

example 1 example 2

It took around a quarter to create each of above examples. O3djs.simple library is anyway only for very basic use. Despite the fact, that this library is simple and does not allow many useful functions, is a bit slow. But OK, JavaScript is slow in general.

On the website there are many more advanced samples showing features that should please professionals.

At the end there are good news that should gratify both basic, and advanced graphics: there is a possibility to convert contend from few programs (e.g. Autodesk 3ds Max, Maya, and Google SketchUp) using COLLADA Converter, and load it directly in o3d.

Reading comments on Google o3d blog I saw many voices pro but also some against this new approach. One is sure: it is worthy of keeping track on it.

Wednesday, April 8, 2009

Simple geo-location with Google Maps API

Update: Google Maps JavaScript API V2 is deprecated.

Today I decided to do something easy and a bit effective at the same time. I chose simple geo-location of visitors using Google Maps Api.

First I will explain step-by-step, as simply and short as possible, basic issues and then, in the end, I will show full working example with (I hope) easy to understand description. 
To use scripts from this tutorial you only need to be familiar with basics of HTML and general idea about object oriented programming but to fully understood or extend mentioned below scripts you should know basics of JavaScript, Ajax, and XHTML.

Let's start. Enjoy!

In short Google Ajax API let you use some of google products like maps, language tools, google search or even earth your websites an easy way. Everything in advantage of Ajax.
More information here.

With Ajax web applications can retrieve data from the server in background (without reloading a website). To achieve this functionality AJAX uses XMLHttpRequest object. This is kind of API build in in web browser that makes possible to communicate with web server (over HTTP protocol) from user-side script (like the JavaScript). More about Ajax here.

Let's insert a simple google map object showing location of a visitor of this page.
In general, using Google Ajax API you don't need to operate on XMLHttpRequestobject in direct way. You will get a google object that can load particular module like maps or search to let you use its method or properties.

General application schema to use Google AJAX API is as follows:

  • in head section of you website you insert script that creates google object for you. ABCDEFG is a key of your website. How to obtain it will be shown later in details.
    <script type="text/javascript" src="http://www.google.com/jsapi?key=ABCDEFG"></script>
  • at this point you have already access to google object. In next step (still in a page's header) we will create main script that will create and manage with module that we want to insert in the website. Basic schema of this script is as follows:
    <script type="text/javascript">
       
        //first we need to load module that we are going to use, and it's version
        google.load(module, version)
       
        //next step is to create a main function that initializes object and manage     
        //its behavior in particular place on website using DOM
        function onload(){
            if (GBrowserIsCompatible()) {
               
                var map = new google.maps.Map2(document.getElementById("map"));
                (...)
                var searchControl = new google.search.SearchControl();
                (...)
                searchControl.draw(document.getElementById("searchcontrol"));
            }    
    
            //now we call the main function using callback function (it's argument is      
    	//another function); this function runs only once - while a document is      
    	//loading
            google.setOnLoadCallback(onload);
    
    </script>

Above code is only a frame and needs to be extended in order to work.

How to get geo-information about a visitor? Google.load includes a property google.loader.ClientLocation that stores information about the client. The most important one is client's IP adderess and geo-loaction data besed on it. From this property we can read following information:

  • ClientLocation.latitude — supplies the low resolution latitude associated with the client's IP address
  • ClientLocation.longitude — supplies the low resolution longitude associated with the client's IP address
  • ClientLocation.address.city — supplies the name of the city associated with the client's IP address

If the IP address is not accessible, then google.loader.ClientLocation is equal to NULL.
Much more detailed introduction to Google AJAX API here.

Now the last think that we need is to know how to use Google Map API. In short, after we have loaded map module we can simply create map object (in this case GMap2 object) a of a given size and in a given (by element id) place on the map.

var map = new GMap2(document.getElementById("map"));
In next step we need to set up this our map:
map.setCenter(new GLatLng(lat, lon), zoom);
where lat and lon are values of latitude and longitude and that we can easily read from google.loader.ClientLocation property. Zoom (as the name indicate) is a value of zoom that we can customize to make the map more/less detailed.
The last think to do is to locate a marker in the right place:
map.addOverlay(new GMarker(new GLatLng(lat, lon)));

Here it is important to remember that the GMarker must take as its argument GLatLng object that stores real geographical coordinates - not the coordinates of the map object. (Much more detiled introduction to Google MAP API here.)

Now let's take everything together!
At first we need to obtain the key. This can be done here: http://code.google.com/apis/ajaxsearch/signup.html. You need to have prepared an address of your website and own a google account. Remember, all your JavaSript code must be placed in head section of the website.
Once you obtain you own key you have to replace it in below script:

<script src='http://www.google.com/jsapi?key=KEY' type='text/javascript'/>
<script language='Javascript' type='text/javascript'>

//skip this in a browser that doesn't support JavaScritp
//<![CDATA[

//load map module version 2
google.load("maps", "2");

//create the main function
function OnLoad() {
        
   //checks if user's browser is supports AJAX 
   if ((GBrowserIsCompatible())) {   
           
   //set initial values for latitude, longitude and zoom
   var lon = 0;
   var lat = 0;
   var zoom = 0;

   //if google.loader is able to discover user information...
   if(google.loader.ClientLocation!=null){

      //read user's informations to following variables
      var country = google.loader.ClientLocation.address.country;
      var region = google.loader.ClientLocation.address.region;
      var city = google.loader.ClientLocation.address.city;
      lat = google.loader.ClientLocation.latitude;
      lon = google.loader.ClientLocation.longitude;
      zoom = 5;

      var locationString = country + ", " + region+ ", " + city;    
      //and now we can insert that information into element with
      //id="location"
      document.getElementById("location").innerHTML = locationString;
   }
   //otherwise print information in location div
   else{
      document.getElementById("location").innerHTML = "not supported";
   }
          
   //create a map object in element with id="map"
   var map = new GMap2(document.getElementById("map"));
   //center map to client's geographic coordination 
   //(it they exists, otherwise use initial values)
   //the last number let u customize your zoom value
   //the grater the number, the more detailed map you will have        
   map.setCenter(new GLatLng(lat, lon), zoom);           
   //add market at visitor's location
   map.addOverlay(new GMarker(new GLatLng(lat, lon)));
  
   //customize the map
   map.setMapType(G_SATELLITE_MAP);
   map.GMap2.disableGoogleBar(); 
   }
else{ 
   //insert information into element with id="location"
   document.getElementById("location").innerHTML = "AJAX not supported";
 }
}

//pass OnLoad() function to call back function
google.setOnLoadCallback(OnLoad);

//]]>
</script>
That is the JavaScript code.
Now the last thing to do is to create container elements on a website. These can be e.g:
<div id="location">loading...</div>
for location information. And for the map:
<div id="map" style="width: 180px; height: 180px; display: block;">loading...</div>

After google.setOnLoadCallback(OnLoad) has been called (at the begging of processing our website)  "loading..."  changes to value of locationString variable and map object. All that assuming that the JavaScript is enabled in your browser and google.loader is able to achieve user location data.

At this moment our geo-location should looks more or less like this:

As you can see, a Google logo and copyrights information doesn't look nice in a map of this size. Of course in any case we should not delete it (that's not so easy, as well). However, there is a way to change its appearance. In order to do so you should add some style information to your website style:
/*TerraMetrics*/
div#map div span{
   right: 2px;
   display:block;
   font-size:9px;
}
/*help link*/
div#map div a{
   right: 2px;
   display:block;
   font-size: 9px;
}
/*Google logo*/
div#map div a img{
   position:relative;
   left: 2px;
   bottom: 140px;
   border: 2px solid #0000FF;
}
You can always get the information about elements  you haven't create using a tool like Web Developer Toolbar for Firefox. That's the effect:

You must keep in mind that google.loader.ClientLocation is only trying to guest a location based on IP address. Everything depends on what kind of Internet connection your visitor has. It may also happen that the location won't be recognized at all. Sorry. Don't be disapointed.

Of course the geo-location is not the most useful element of you website. However playing with google maps is a good exercise that let you enable some more cheerful functionality of your blog or website like presenting a weather forecast or news related with visitor's location.