1 2 3 4 5 6 7 8 9 10 11 12 |
var data = [ {'id':1, 'title':'Ejemplo 1', 'lat':43.3025021,'lng':-8.512655300000006,'icono':'icono1.image'}, {'id':2, 'title':'Ejemplo 2', 'lat':43.3028264,'lng':-8.513041899999962,'icono':'icono1.image'}, {'id':3, 'title':'Ejemplo 3', 'lat':43.3009559,'lng':-8.510700600000064,'icono':'icono2.image'}, {'id':4, 'title':'Ejemplo 4', 'lat':43.2996359,'lng':-8.50846690000003,'icono':'icono3.image'}, {'id':5, 'title':'Ejemplo 5', 'lat':43.30111489999999,'lng':-8.510778999999957,'icono':'icono2.image'}, {'id':6, 'title':'Ejemplo 6', 'lat':43.29966,'lng':-8.508889899999986,'icono':'icono3.image'}, {'id':7, 'title':'Ejemplo 7', 'lat':43.3015562,'lng':-8.511780300000055,'icono':'icono2.image'}, {'id':8, 'title':'Ejemplo 8', 'lat':43.3038683,'lng':-8.510297400000013,'icono':'icono2.image'}, {'id':9, 'title':'Ejemplo 9', 'lat':43.299981,'lng':-8.509676300000024,'icono':'icono1.image'}, {'id':10, 'title':'Ejemplo 10', 'lat':43.3009559,'lng':-8.510700600000064,'icono':'icono2.image'} ]; |
1 2 3 4 5 6 7 8 9 10 |
google.maps.event.addListener(marker, 'spider_format', function(status) { var iconURL = status == OverlappingMarkerSpiderfier.markerStatus.SPIDERFIED ? eval(markerData.icono) : status == OverlappingMarkerSpiderfier.markerStatus.SPIDERFIABLE ? iconogrupo.image : status == OverlappingMarkerSpiderfier.markerStatus.UNSPIDERFIABLE ? eval(markerData.icono) : null; marker.setIcon({ url: iconURL, }); }); |
Explicación de como se cambian los iconos de cada punto
Si los puntos se juntan lo suficiente para que parezcan uno son SPIDERFIABLE, y por lo tanto mostramos el icono de agrupación. En el momento que se aumenta el zoom y estos puntos se separan los suficiente pasan a ser UNSPIDERFIABLE, excepto en el caso de que esten en las mismas coordenadas, en cuyo caso son siempre SPIDERFIABLE. Si 2 o mas puntos están en la misma posición siempre van a ser SPIDERFIABLE excepto cuando se clica sobre ellos que se desagregan y pasan a ser SPIDERFIED y por tanto hay que asignarles su icono por defecto. Una vez que clico en alguno de estos puntos vuelven a ser SPIDERFIABLE y por tanto se le pone el icono de agrupación. Lo mismo que si se clica en otro punto que no sean estos, la libraría considera esos puntos como SPIDERFIABLE y se pone igualmente el icono de grupo. El estado SPIDERFIABLE quiere decir que el punto esta “lo suficientemente cercano” a otro o incluso en el mismo punto como para que se agrupen y se muestre el icono de agrupación. Este “suficientemente cercano” lo determina la librería y se puede configurar con la propiedad nearbyDistance que por defecto tiene el valor de 20 pixels de radio. El estado SPIDERFIED significa que el punto formaba parte de una agrupación y al clicar encima se desagrega y hay que ponerle el icono que le pertenece hasta que vuelva a su estado SPIDERFIABLE. La librería calcula en todo momento la cercanía de los puntos y a partir de este calculo determina que puntos son SPIDERFIABLE, SPIDERFIED y UNSPIDERFIABLE y esto es lo que lanza el evento “spider_format” para cambiar el icono. Cada vez que el usuario interactua con el mapa, bien clicando en algún punto o bien aumentando o disminuyendo el zoom se llama a la función “spider_format” que se encarga de recalcular y mostrar el icono correspondiente y en caso de que sea necesario agrupar o desagrupar puntos le pinta el icono correspondiente. El código en si, una vez que entiende el funcionamiento de los diferentes estados no tiene mayor complicación. Lo único que hay que tener en cuenta son 2 cosas:- En el json para cada punto indico que icono hay que cargar. Esta información como en el json va como una cadena, al asignarla en la generación del icono y al cambiar el icono hay que evaluarla con la función eval de javascript para que obtenga su verdadero valor
- Los datos de los iconos hay que meterlos dentro de la función addMarkerWithData para que funcione la clausura. Si se se sacan fuera ya no va a funcionar la asignación del icono correspondiente. Si no tienes claro como funcionan las clausuras te recomiendo visitar los siguientes links:
https://developer.mozilla.org/es/docs/Web/JavaScript/Closures http://www.jmocana.eu/javascript-clausuras/
Aquí teneis el código completo del ejemplo en html, lo único que faltaría es el json que teneis al principio con los puntos y que se carga como archivo externo «datos.json» (línea 16) y los iconos que estamos usando que los podeis sustitutir por los que querais. Como pódeis ver es casi idéntico al original con excepción de las pequeñas modificaciones comentadas
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <title>Mi Fancy demo — Overlapping Marker Spiderfier</title> <style> html, body { height: auto; font: 14px 'Helvetica Neue', 'Arial', sans-serif; } p { margin: 0.75em 0; } ul { margin: 0; padding: 0; } a { cursor: pointer; } #map_element { position: absolute; bottom: 0; left: 0; right: 0; top: 0; } #legend { position: absolute; right: 20px; top: 20px; background: rgba(0,0,0,0.5); color: #fff; } #legend ul { padding: 10px 20px 10px 10px; margin: 0 0 0 20px; } </style> <script type="text/javascript" src="datos.json"></script> </head> <body> <div id="map_element"></div> <div id="legend"> Ejemplo básico de cambio de iconos <ul> <li><b>No se mueven</li> <li><b>No se añaden iconos</li> <li><b>No se eliminan ni ocultan</li> </ul> </div> <script>var isIE = false;</script><!--[if IE]><script>isIE = true;</script><![endif]--> <script> // NOTES // this example demonstrates all features: // each marker has its own colour, so formatting is done with a marker-level listener // markers can be moved (by dragging), added (by right-clicking on the map), and // removed or temporarily hidden (by right-clicking on a marker) //cargo los datos del json externo window.mapData = data; var mapLibsReady = 0; function mapLibReadyHandler() { if (++ mapLibsReady < 2) return; var mapElement = document.getElementById('map_element'); var map = new google.maps.Map(mapElement, { center: { lat: 43.302, lng: -8.512 }, zoom: 12 }); var iw = new google.maps.InfoWindow(); function iwClose() { iw.close(); } google.maps.event.addListener(map, 'click', iwClose); var oms = new OverlappingMarkerSpiderfier(map); for (var i = 0, len = window.mapData.length; i < len; i ++) addMarkerWithData(window.mapData[i]); function addMarkerWithData(markerData) { //genero los marcadores var iconogrupo = new google.maps.MarkerImage(); iconogrupo.image = 'img/grupo.png'; var tamanoiconogrupo = new google.maps.Size(40,40); iconogrupo.iconSize = tamanoiconogrupo; iconogrupo.iconAnchor = new google.maps.Point(20,20); iconogrupo.imageMap = [0,0, 39,0, 39,39, 0,39]; var icono1 = new google.maps.MarkerImage(); icono1.image = 'img/icono1.png'; icono1.iconSize = tamanoiconogrupo; icono1.iconAnchor = new google.maps.Point(20,20); icono1.imageMap = [0,0, 39,0, 39,39, 0,39]; var icono2 = new google.maps.MarkerImage(); icono2.image = 'img/icono2.png'; var tamanoiconarabeneg = new google.maps.Size(40,40); icono2.iconSize = tamanoiconogrupo; icono2.iconAnchor = new google.maps.Point(20,20); icono2.imageMap = [0,0, 39,0, 39,39, 0,39]; var icono3 = new google.maps.MarkerImage(); icono3.image = 'img/icono3.png'; icono3.iconSize = tamanoiconogrupo; icono3.iconAnchor = new google.maps.Point(20,20); icono3.imageMap = [0,0, 39,0, 39,39, 0,39]; var marker = new google.maps.Marker({ position: markerData, icon: eval(markerData.icono), optimized: ! isIE // makes SVG icons work in IE }); google.maps.event.addListener(marker, 'click', iwClose); google.maps.event.addListener(marker, 'spider_format', function(status) { var iconURL = status == OverlappingMarkerSpiderfier.markerStatus.SPIDERFIED ? eval(markerData.icono) : status == OverlappingMarkerSpiderfier.markerStatus.SPIDERFIABLE ? iconogrupo.image : status == OverlappingMarkerSpiderfier.markerStatus.UNSPIDERFIABLE ? eval(markerData.icono) : null; marker.setIcon({ url: iconURL, }); }); oms.addMarker(marker, function(e) { iw.setContent('Id: ' + markerData.id + '<br /> ' + markerData.title); iw.open(map, marker); }); } window.map = map; // for debugging/exploratory use in console window.oms = oms; // ditto } </script> <script async defer src="https://maps.google.com/maps/api/js?v=3&callback=mapLibReadyHandler&key=AIzaSyCvj6Tkp0HspM1suRUGU4wmynra9Ow__Cw"></script> <script async defer src="https://cdnjs.cloudflare.com/ajax/libs/OverlappingMarkerSpiderfier/1.0.3/oms.min.js?spiderfier_callback=mapLibReadyHandler"></script> </body> </html> /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ |