I\'m attempting to draw many circles (around 1000) on a google map, at various locations and sizes, and then binding a click event to them. But this many calls of new goog
Here is yet another example that demonstrates how to render multiple objects on Google Map using Overlay approach. Since the performance could degrade considerably while the amount of objects (e.g. google.maps.Circle
) is increasing, it is proposed to render objects using canvas
element instead of div
one.
Example
The example demonstrates how to render 1k objects (cities)
var overlay;
USCitiesOverlay.prototype = new google.maps.OverlayView();
function USCitiesOverlay(map) {
this._map = map;
this._cities = [];
this._radius = 6;
this._container = document.createElement("div");
this._container.id = "citieslayer";
this.setMap(map);
this.addCity = function (lat, lng,population) {
this._cities.push({position: new google.maps.LatLng(lat,lng),population: population});
};
}
USCitiesOverlay.prototype.createCityIcon = function (id,pos,population) {
var cityIcon = document.createElement('canvas');
cityIcon.id = 'cityicon_' + id;
//calculate radius based on poulation
this._radius = population / 100000;
cityIcon.width = cityIcon.height = this._radius * 2;
cityIcon.style.width = cityIcon.width + 'px';
cityIcon.style.height = cityIcon.height + 'px';
cityIcon.style.left = (pos.x - this._radius) + 'px';
cityIcon.style.top = (pos.y - this._radius) + 'px';
cityIcon.style.position = "absolute";
var centerX = cityIcon.width / 2;
var centerY = cityIcon.height / 2;
var ctx = cityIcon.getContext('2d');
ctx.fillStyle = 'rgba(160,16,0,0.6)';
ctx.beginPath();
ctx.arc(centerX, centerY, this._radius, 0, Math.PI * 2, true);
ctx.fill();
return cityIcon;
};
USCitiesOverlay.prototype.ensureCityIcon = function (id,pos,population) {
var cityIcon = document.getElementById("cityicon_" + id);
if(cityIcon){
cityIcon.style.left = (pos.x - this._radius) + 'px';
cityIcon.style.top = (pos.y - this._radius) + 'px';
return cityIcon;
}
return this.createCityIcon(id,pos,population);
};
USCitiesOverlay.prototype.onAdd = function () {
var panes = this.getPanes();
panes.overlayLayer.appendChild(this._container);
};
USCitiesOverlay.prototype.draw = function () {
var zoom = this._map.getZoom();
var overlayProjection = this.getProjection();
var container = this._container;
this._cities.forEach(function(city,idx){
var xy = overlayProjection.fromLatLngToDivPixel(city.position);
var cityIcon = overlay.ensureCityIcon(idx,xy,city.population);
container.appendChild(cityIcon);
});
};
USCitiesOverlay.prototype.onRemove = function () {
this._container.parentNode.removeChild(this._container);
this._container = null;
};
function getRandomInterval(min, max) {
return Math.random() * (max - min) + min;
}
function generateCityMap(count) {
var citymap = [];
var minPos = new google.maps.LatLng(49.25, -123.1);
var maxPos = new google.maps.LatLng(34.052234, -74.005973);
for(var i = 0; i < count;i++)
{
var lat = getRandomInterval(minPos.lat(),maxPos.lat());
var lng = getRandomInterval(minPos.lng(),maxPos.lng());
var population = getRandomInterval(100000,1000000);
citymap.push({
location: new google.maps.LatLng(lat, lng),
population: population
});
}
return citymap;
}
function initialize() {
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(37.09024, -95.712891),
mapTypeId: google.maps.MapTypeId.TERRAIN
};
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
overlay = new USCitiesOverlay(map);
//overlay.addCity(40.714352, -74.005973); //chicago
//overlay.addCity(40.714352, -74.005973); //newyork
//overlay.addCity(34.052234, -118.243684); //losangeles
//overlay.addCity(49.25, -123.1); //vancouver
var citymap = generateCityMap(1000);
citymap.forEach(function(city){
overlay.addCity(city.location.lat(), city.location.lng(),city.population);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px;
}