Sunday, May 16, 2010

Mixing Google Maps with Raphael JS (II)

In this second part of this "mix" we will add a transparent layer over the Google Maps map. The purpose is to use the layer as a working area for drawing shapes.
The shapes built on this layer can be added to the map as shown on this page. This designer is useful as a tool when you want to add custom shapes for example not coding, but visually.

Prerequisites:
Besides the loading of Google Maps script and Raphael JS script, in the head of the document we load two libraries, jQuery and jQuery UI and a stylesheet to use together with jQuery UI. You can use any other library you like, but this is what I have used.

Page structure:
a) Head:
- google maps;
- Raphael JS script;
- jQuery;
- jQuery UI;
- CSS file;
- the JavaScript which will be used to put out designer on work.
b) Body:
- a div which will contain the Google map (id=map_canvas);
- a div which will be positioned absolutely on the same coordinates as the Google map, with a z-index value that will put it on the front (id=r_canvas);
- a div which will be used as a handler to move/select objects.

Strategy for the code building:
-first, we add the map:
function initialize() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
}
}
The rest of the code has to be positioned inside the 'initialize()' function.
- then we add the Raphael JS object which is the working area:
var r = Raphael(document.getElementById("r_canvas"), 500, 300);
- now we add a mouse position function to the document:
$("#canvas").mousemove(function(e){
xPos=e.pageX;
yPos=e.pageY;
});
var position={
"x":'0',
"y":'0'
} ;
This code will be used as follows:
"xPos" and "yPos" are declared with local scope, to be updated dynamically when the mouse moves.
"position" is declared globally, but will be used only on "onmousedown" document event.

Make a chart of events which are common for jQuery,Raphael JS and Google Maps that will be used.

DOM jQuery Raphael JS Google Maps
onmousedown mousedown mousedown mousedown
onmousemove mousemove mousemove mousemove
onmouseup mouseup mouseup mouseup
onclick click click click

The usage is this:
DOM:
document.onclick(function(alert("test")));
jQuery
$(document).click(function(){alert("test")})
Raphael JS
Same as DOM, but the event can be attached only to a Raphael JS object.

Google Maps
It can be attached only to a Google map object.
GEvent.addListener(map, "click", function() {
alert("test");
});

With the above events you can start to build the engine.
These events will pass actions and information from one library to another as required.
In our designer we use Raphael JS for its enhancements,such as shape rotation,custom shapes, control and more, but we could design very well without any library, just with Google Maps

Friday, May 14, 2010

Similar results with Google Maps geocoding service

How to display all the results found by the Google Mas geocoding service.
The geocoding service returns a set of results where the first one in the set should be the most accurate. Of course, the resulting set can be influenced by the map options.



Follow the comments in the script that describes the functionality.
var map;
var geocoder;

function initialize() {
map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(34, 0), 1);
geocoder = new GClientGeocoder();
}

// addAddressToMap() is called when the geocoder returns an
// answer. It adds a marker to the map with an open info window
// showing the nicely formatted version of the address and the country code.
function addAddressToMap(response) {
map.clearOverlays();
if (!response || response.Status.code != 200) {
alert("Sorry, we were unable to geocode that address");
} else {


// clear the container where will appear the similarities
document.getElementById('s').innerHTML='';
//this is the marker that will be placed on the map
place = response.Placemark[0];
point = new GLatLng(place.Point.coordinates[1],
place.Point.coordinates[0]);
marker = new GMarker(point);
map.addOverlay(marker);
marker.openInfoWindowHtml(place.address + '<br>' +
'<b>Country code:</b> ' + place.AddressDetails.Country.CountryNameCode);
//now we add the similarities

//'lgt' is the total number of similaties (including the one placed on the map)
var lgt=response.Placemark.length;
//now we loop through each similarity
for(i=0;i<lgt;i++){
var mn=response.Placemark[i];
var mnpoint=new GLatLng(mn.Point.coordinates[1],
mn.Point.coordinates[0]);
markere = new GMarker(mnpoint);
//and add it on our list
document.getElementById('s').innerHTML+=mn.address+'<br/>';
}

}
}

// showLocation() is called when you click on the Search button
// in the form. It geocodes the address entered into the form
// and adds a marker to the map at that location.
function showLocation() {
var address = document.forms[0].q.value;
geocoder.getLocations(address, addAddressToMap);
}

// findLocation() is used to enter the sample addresses into the form.
function findLocation(address) {
document.forms[0].q.value = address;
showLocation();
}