Skip to content

Instantly share code, notes, and snippets.

@sheldon
Created November 19, 2009 11:13
Show Gist options
  • Save sheldon/238698 to your computer and use it in GitHub Desktop.
Save sheldon/238698 to your computer and use it in GitHub Desktop.
google.load('jquery', '1.3');
google.load("maps", "2");
google.load("visualization", "1", {packages:["linechart"]});
google.setOnLoadCallback(function(){
$(document).ready(function(){
var map = new google.maps.Map2(document.getElementById("main_map"));
map.setCenter(new google.maps.LatLng(37.4419, -122.1419), 5);
// generate random points
var all_markers = new Array();
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
for (var i = 0; i < 100; i++) all_markers.push({"lat":southWest.lat() + latSpan * Math.random(), "lng":southWest.lng() + lngSpan * Math.random()});
var clusters = [];
var max_distance = calc_max_distance();
var singles = [];
var checked_markers = all_markers.slice();
while(checked_markers.length > 0){
var current_marker = checked_markers.pop();
for (var i = clusters.length - 1; i >= 0; i--){
if(haversine_distance(current_marker,clusters[i].center) < max_distance){
}
};
for (var i = checked_markers.length - 1; i >= 0; i--){
if(haversine_distance(current_marker,checked_markers[i]) < max_distance){
close_marker = checked_markers.splice(i,1);
close_marker = close_marker[0];
if(current_marker.cluster) addMarkerToCluster(close_marker, current_marker.cluster);
else createCluster(current_marker,close_marker);
}
}
if(!current_marker.cluster) singles.push(current_marker);
}
//console.log(clusters);
//console.log(singles);
for(var i = 0; i < clusters.length; i++){
var centerpoint = new GMarker(new GLatLng(clusters[i].markers[0].lat,clusters[i].markers[0].lng));
centerpoint.other_markers = clusters[i].markers;
//map.addOverlay(centerpoint);
drawCircle(new GLatLng(clusters[i].markers[0].lat, clusters[i].markers[0].lng), max_distance, 32);
GEvent.addListener(centerpoint, "click", function() {
display_markers(this.other_markers);
});
}
for(var i = 0; i < all_markers.length; i++){
map.addOverlay(new GMarker(new GLatLng(all_markers[i].lat,all_markers[i].lng)));
}
function addMarkerToCluster(marker,cluster){
cluster.markers.push(marker);
marker.cluster = cluster;
}
function combineClusters(cluster1,cluster2){
// if(cluster1.markers.length > cluster2.markers.length){
// var tmp_cluster = cluster1;
// cluster1 = cluster2;
// cluster2 = tmp_cluster;
// }// swap to only step over the smallest one
for (var i=0; i < cluster1.markers.length; i++) {
addMarkerToCluster(cluster1.markers[i],cluster2);
};
}
function createCluster(){
var new_cluster = {markers:[]};
for (var i=0; i < arguments.length; i++) {
new_cluster.markers.push(arguments[i]);
};
clusters.push(new_cluster);
return new_cluster;
}
function display_markers(markers){
for(var i in markers){
map.addOverlay(new GMarker(new GLatLng(markers[i].lat,markers[i].lng)));
}
}
function calc_max_distance() { //gets distance in km of 32 pixels
var p1 = map.fromContainerPixelToLatLng(new GPoint(0,0));
var p2 = map.fromContainerPixelToLatLng(new GPoint(32,32));
return p1.distanceFrom(p2) / 1000;
}
function drawCircle(center, radius, nodes, liColor, liWidth, liOpa, fillColor, fillOpa){
//calculating km/degree
var latConv = center.distanceFrom(new GLatLng(center.lat()+0.1, center.lng()))/100;
var lngConv = center.distanceFrom(new GLatLng(center.lat(), center.lng()+0.1))/100;
//Loop
var points = [];
var step = parseInt(360/nodes)||10;
for(var i=0; i<=360; i+=step)
{
var pint = new GLatLng(center.lat() + (radius/latConv * Math.cos(i * Math.PI/180)), center.lng() +
(radius/lngConv * Math.sin(i * Math.PI/180)));
points.push(pint);
bounds = new GLatLngBounds();
bounds.extend(pint); //this is for fit function
}
points.push(points[0]); // Closes the circle, thanks Martin
fillColor = fillColor||liColor||"#0055ff";
liWidth = liWidth||2;
var poly = new GPolygon(points,liColor,liWidth,liOpa,fillColor,fillOpa);
map.addOverlay(poly);
}
});
});
Number.prototype.toRad = function() { // convert degrees to radians
return this * Math.PI / 180;
}
function haversine_distance(point_a,point_b){
var R = 6371; // km
var dLat = (point_a.lat - point_b.lat).toRad();
var dLon = (point_a.lng - point_b.lng).toRad();
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(point_b.lat.toRad()) * Math.cos(point_a.lat.toRad()) *
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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment