Etiquetes

, , ,

Avui, un apunt molt més tècnic però que vull deixar compartit, per si a algú li fa falta. En algunes ocasions haureu vist webs que, en un mapa de Google Maps, agrupen els punts (markers) de forma aut0màtica. Buscant entre els que ho feien vaig trobar un javascript interessant i prou senzill d’implementar, així com funcions PHP per calcular-ho des del servidor.

El primer cas, en Javascript, és MarkerClusterer per la API V3 de Google Maps. D’entrada es crea el mapa i els markers, i quan ja estan creats s’agrupen en un cluster. S’han de tenir en compte algunes bones pràctiques com ara mantenir tots els markers en una matriu per tal de poder-los esborrar cada cop que hi ha una actualització per haver mogut el mapa o canviat el zoom. La documentació que incorpora és molt breu, però suficient. Si voleu utilitzar-lo amb càrregues segons els canvis d’ubicació al mapa, només us fa falta saber que l’event bounds_changed , per ara, té un error conegut però no solventat, així que des de Google es recomana substituir-lo per idle. Us estalviarà mals de cap, ja que bounds_changed repeteix una mateixa crida diverses vegades seguides.

De fet, ben aviat veureu un projecte que incorpora aquesta característica i algunes d’altres de Google Maps, ara que ja suporta SSL en la versió estàndard. I durant la preparació del projecte, m’he adonat d’algunes novetats que m’havien passat per alt respecte a la versió anterior de l’API de Google Maps; o que simplement no havia utilitzat mai. Per exemple, ha desaparegut la funció de càlcul de distància entre dos markers, així que si la necessiteu, podeu recórrer a una funció pròpia (que jo vaig trobar buscant per la xarxa):

google.maps.LatLng.prototype.distanceFrom = function(newLatLng) {
var lat1 = this.lat();
var radianLat1 = lat1 * ( Math.PI / 180 );
var lng1 = this.lng();
var radianLng1 = lng1 * ( Math.PI / 180 );
var lat2 = newLatLng.lat();
var radianLat2 = lat2 * ( Math.PI / 180 );
var lng2 = newLatLng.lng();
var radianLng2 = lng2 * ( Math.PI / 180 );
var earth_radius = 6378.1; // (km = 6378.1) OR (miles = 3959) – radius of the earth
var diffLat = ( radianLat1 – radianLat2 );
var diffLng = ( radianLng1 – radianLng2 );
var sinLat = Math.sin( diffLat / 2 );
var sinLng = Math.sin( diffLng / 2 );
var a = Math.pow(sinLat, 2.0) + Math.cos(radianLat1) * Math.cos(radianLat2) * Math.pow(sinLng, 2.0);
var distance = earth_radius * 2 * Math.asin(Math.min(1, Math.sqrt(a)));
return distance;
}

Així com la capacitat de poder rebre les coordenades superior esquerra i inferior dreta:

var coordenades=map.getBounds()
var coordDalt = coordenades.getSouthWest();
var coordBaix = coordenades.getNorthEast();

També podeu saber quin és el zoom màxim de la zona que es visualitza (vegeu MaxZoomService) o localitzar fàcilment coordenades d’adreces (Geocoder, recomanant no buscar automàticament noms de ciutats sols, ja que Vic, per exemple, us pot dur on no us esperàveu, com als Estat Units).

Però no només de Google Maps s’ha de viure: necessitava en PHP, a partir d’una matriu que conté informació dels elements, tals com la latitud i la longitud, agrupar-los en la mateixa matriu per passar-los després a un altre procés diferent de Google Maps. Com fer-ho? Un article d’un blog no gaire nou em va solucionar el problema. A Introduction to Marker Clustering With Google Maps, hi podeu trobar algunes funcions interessants, basades en la fòrmula del Haversine. Evidentment, en aquest cas les funcions us les podeu adaptar segons les vostres necessitats (sobretot a l’hora d’agrupar l’array, jo utilitzava una estructura una mica diferent), però la idea és bona, i això demostra que hi ha recursos amagats molt interessants per la xarxa!

Anuncis