I'm using google maps in my application, and I have a webserver with a databse filled with lat/lon values. I want to mark them on the map, but I also want to cluster them together if they are within a certain pixel-distance of eachother.
I figure if I retrieve all my points from the database, I should be able to do something like this (pseudocode):
clusters[];
while(count(points)) {
cluster[];
point = points.pop();
boundingbox = pixelsToBB(point, pixeldistance, zoomlevel);
query = "select * from database where lat > boundingbox.minlat
and lat < boundingbox.maxlat and lng > boundingbox.minlng
and lng < boundingbox.maxlng";
for (result in executedquery) {
cluster[] += result;
points.remove(result);
}
clusters[] += cluster;
}
pixelsToBB(point, distance, zoomlevel) {
center = convertXY(point, zoomlevel);
maxlng = convertToLng(center.X, distance, zoomlevel);
minlng = convertToLng(center.X, -distance, zoomlevel);
minlat = convertToLat(center.Y, -distance, zoomlevel);
maxlat = convertToLat(center.Y, distance, zoomlevel);
return boundingbox(maxlng, maxlat, minlng, minlat);
}
What would my pixelsToBB function need to do with the zoomlevel? OR rather what would my convertToXY, convertToLng and convertToLat need to do? Am I thinking about this the right way, or are there any better ways to do it? I'm not even sure what to search for, so if it's been asked before I'm sorry.
Using Google Maps API v3:
var latLng = // your position object here
var projection = map.getProjection();
var bounds = map.getBounds();
var topRight = projection.fromLatLngToPoint(bounds.getNorthEast());
var bottomLeft = projection.fromLatLngToPoint(bounds.getSouthWest());
var scale = Math.pow(2, map.getZoom());
var worldPoint = projection.fromLatLngToPoint(latLng);
return [Math.floor((worldPoint.x - bottomLeft.x) * scale), Math.floor((worldPoint.y - topRight.y) * scale)];