forked from qwerty/tupali
244 lines
7.4 KiB
PHP
244 lines
7.4 KiB
PHP
<!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.
|
|
map.on('click', 'unclustered-point', function (e) {
|
|
var coordinates = e.features[0].geometry.coordinates.slice();
|
|
// var mag = e.features[0].properties.mag;
|
|
var descripcion = e.features[0].properties.description;
|
|
|
|
// Ensure that if the map is zoomed out such that
|
|
// multiple copies of the feature are visible, the
|
|
// popup appears over the copy being pointed to.
|
|
while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
|
|
coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
|
|
}
|
|
|
|
new mapboxgl.Popup()
|
|
.setLngLat(coordinates)
|
|
// .setHTML( 'magnitude: ' + mag + '<br>Was there a tsunami?: ' + tsunami )
|
|
.setHTML( descripcion )
|
|
.addTo(map);
|
|
});
|
|
*/
|
|
// 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.descripcion;
|
|
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()
|
|
.setLngLat(coords)
|
|
.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>
|