Created
November 19, 2009 11:13
-
-
Save sheldon/238698 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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