<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Create and style clusters</title> <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /> <link rel="stylesheet" href="librerias/bootstrap/css/bootstrap.min.css" /> <script src="https://api.mapbox.com/mapbox-gl-js/v1.10.0/mapbox-gl.js"></script> <link href="https://api.mapbox.com/mapbox-gl-js/v1.10.0/mapbox-gl.css" rel="stylesheet" /> <script src="https://code.jquery.com/jquery-3.3.1.js" ></script> <script src='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v1.3.0/mapbox-gl-geocoder.js'></script> <link rel='stylesheet' href='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v1.3.0/mapbox-gl-geocoder.css' type='text/css' /> <link href='https://www.mapbox.com/base/latest/base.css' rel='stylesheet' /> <link rel='stylesheet' href='./milfs/css/mapero.css' type='text/css' /> <link rel="canonical" href="https://labs.mapbox.com/bites/00281/" > </head> <body> <div id="map"></div> <script> mapboxgl.accessToken = 'pk.eyJ1IjoiaHVtYW5vIiwiYSI6IlgyRTFNdFEifQ.OmQBXmcVg_zq-vMpr8P5vQ'; var map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/dark-v10', center: [-72, 4], zoom: 5 }); map.on('load', function () { map.addSource("addresses", { type: "geojson", data: 'http://localhost/tupali/archivos/74.geojson', cluster: true, clusterMaxZoom: 14, // Max zoom to cluster points on clusterRadius: 50 // Radius of each cluster when clustering points (defaults to 50) }); /// estilos cluster map.addLayer({ id: 'clusters', type: 'circle', source: 'addresses', filter: ['has', 'point_count'], paint: { // Use step expressions (https://docs.mapbox.com/mapbox-gl-js/style-spec/#expressions-step) // with three steps to implement three types of circles: // * Blue, 20px circles when point count is less than 100 // * Yellow, 30px circles when point count is between 100 and 750 // * Pink, 40px circles when point count is greater than or equal to 750 'circle-color': [ 'step', ['get', 'point_count'], '#51bbd6', 100, '#f1f075', 750, '#f28cb1' ], 'circle-radius': [ 'step', ['get', 'point_count'], 20, 100, 30, 750, 40 ] } }); map.addLayer({ id: 'cluster-count', type: 'symbol', source: 'addresses', filter: ['has', 'point_count'], layout: { 'text-field': '{point_count_abbreviated}', 'text-font': ['DIN Offc Pro Medium', 'Arial Unicode MS Bold'], 'text-size': 12 } }); map.addLayer({ id: 'unclustered-point', type: 'circle', source: 'addresses', filter: ['!', ['has', 'point_count']], paint: { 'circle-color': '#11b4da', 'circle-radius': 4, 'circle-stroke-width': 1, 'circle-stroke-color': '#fff' } }); /// estilos cluster // inspect a cluster on click map.on('click', 'clusters', function (e) { var features = map.queryRenderedFeatures(e.point, { layers: ['clusters'] }); var clusterId = features[0].properties.cluster_id; map.getSource('addresses').getClusterExpansionZoom( clusterId, function (err, zoom) { if (err) return; map.easeTo({ center: features[0].geometry.coordinates, zoom: zoom }); } ); }); // When a click event occurs on a feature in // the unclustered-point layer, open a popup at // the location of the feature, with // description HTML from its properties. // Store IDs and cluster/marker HTMLElements const markers = new Map(); function updateMarkers(){ const features = map.querySourceFeatures('addresses'); const keepMarkers = []; for (let i = 0; i < features.length; i++) { const coords = features[ i ].geometry.coordinates; const props = features[ i ].properties; const icono = features[ i ].properties.imagen; const descripcion = features[ i ].properties.description; const featureID = features[ i ].properties.control; const clusterID = props.cluster_id || null; if (props.cluster && markers.has('cluster_'+clusterID)) { //Cluster marker is already on screen keepMarkers.push('cluster_'+clusterID); } else if (props.cluster) { //This feature is clustered, create an icon for it and use props.point_count for its count /* var el = document.createElement('div'); el.className = 'mapCluster'; el.style.width = '60px'; el.style.height = '60px'; el.style.textAlign = 'center'; el.style.color = 'white'; el.style.background = '#16d3f9'; el.style.borderRadius = '50%'; el.innerText = props.point_count; const marker = new mapboxgl.Marker(el).setLngLat(coords); marker.addTo(map); keepMarkers.push('cluster_'+featureID); markers.set('cluster_'+clusterID,el); */ } else if (markers.has(featureID)) { //Feature marker is already on screen keepMarkers.push(featureID); } else { //Feature is not clustered and has not been created, create an icon for it const el = new Image(); // el.style.backgroundImage = 'url(https://placekitten.com/g/50/50)'; el.style.backgroundImage = 'url('+icono+')'; el.className = 'mapMarker'; el.style.width = '50px'; el.style.height = '50px'; // el.style.borderRadius = '50%'; el.dataset.type = props.type; el.addEventListener('click', function() { // window.alert("Hola mundo"); var popup = new mapboxgl.Popup({ closeOnClick: false }) .setLngLat(coords) //.setHTML(descripcion) .setHTML(descripcion) .addTo(map); }); const marker = new mapboxgl.Marker(el).setLngLat(coords); marker.addTo(map); keepMarkers.push(featureID); markers.set(featureID,el); } } //Let's clean-up any old markers. Loop through all markers markers.forEach((value,key,map) => { //If marker exists but is not in the keep array if (keepMarkers.indexOf(key) === -1) { console.log('deleting key: '+key); //Remove it from the page value.remove(); //Remove it from markers map map.delete(key); } }); }; map.on('data', function (e) { if (e.sourceId !== 'addresses' || !e.isSourceLoaded) return; map.on('moveend', updateMarkers); // moveend also fires on zoomend updateMarkers(); }); map.on('mouseenter', 'clusters', function () { map.getCanvas().style.cursor = 'pointer'; }); map.on('mouseleave', 'clusters', function () { map.getCanvas().style.cursor = ''; }); }); </script> </body> </html>