labcluster

This commit is contained in:
humano 2020-05-14 09:07:46 -05:00
parent e3fe6f6194
commit 1d4fb0cf09
2 changed files with 415 additions and 224 deletions

243
labcluster.php Normal file
View File

@ -0,0 +1,243 @@
<!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>

View File

@ -1,238 +1,186 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Tupale.co</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.7.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.7.0/mapbox-gl.css' rel='stylesheet' />
<link href='https://www.mapbox.com/base/latest/base.css' rel='stylesheet' />
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
.map-overlay {
position: absolute;
width: 180px;
top: 0;
left: 10px;
padding: 10px;
margin-left: 5px;
margin-top: 2px;
margin-bottom: 2px;
margin-right: 5px;
z-index: 1;
}
.map-overlay .map-overlay-inner {
background: rgba(0, 0, 0, .8);
color: #fff;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.10);
border-radius: 3px;
padding: 10px;
margin-bottom: 10px;
z-index: 1;
}
.map-overlay-inner fieldset {
border: none;
padding: 0;
margin: 0 0 10px;
z-index: 1;
}
/* Dark attribution */
.mapboxgl-ctrl.mapboxgl-ctrl-attrib {
background: rgba(0, 0, 0, .8);
}
.mapboxgl-ctrl.mapboxgl-ctrl-attrib a {
color: #fff;
}
/* Dark popup */
<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>
.mapboxgl-popup-anchor-bottom-left .mapboxgl-popup-tip,
.mapboxgl-popup-anchor-bottom-right .mapboxgl-popup-tip,
.mapboxgl-popup-anchor-bottom .mapboxgl-popup-tip {
border-top-color: #202020;
}
.mapboxgl-popup-anchor-top-left .mapboxgl-popup-tip,
.mapboxgl-popup-anchor-top-right .mapboxgl-popup-tip,
.mapboxgl-popup-anchor-top .mapboxgl-popup-tip {
border-bottom-color: #202020;
}
.mapboxgl-popup-anchor-right .mapboxgl-popup-tip {
border-left-color: #202020;
}
.mapboxgl-popup-anchor-left .mapboxgl-popup-tip {
border-right-color: #202020;
}
#popup-menu ul,
#menu li {
margin: 0;
padding: 0;
z-index: 100;
}
.mapboxgl-ctrl-group {
-webkit-filter: invert(100%);
}
.loader {
margin: -10px 0 0 -250px;
height: 100px;
width: 20%;
position: fixed;
text-align: center;
padding: 1em;
top: 50%;
left: 50%;
margin: 0 auto 1em;
z-index: 9999;
}
/*
Set the color of the icon
*/
svg path,
svg rect {
fill: #FF6700;
}
</style>
<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>
<div class='map-overlay top'>
<div class='map-overlay-inner'>
</div>
</div>
<div class="loader loader--style1" title="0" id="loader">
<svg version="1.1" id="loader-1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="40px" height="40px" viewBox="0 0 40 40" enable-background="new 0 0 40 40" xml:space="preserve">
<path opacity="0.2" fill="#000" d="M20.201,5.169c-8.254,0-14.946,6.692-14.946,14.946c0,8.255,6.692,14.946,14.946,14.946
s14.946-6.691,14.946-14.946C35.146,11.861,28.455,5.169,20.201,5.169z M20.201,31.749c-6.425,0-11.634-5.208-11.634-11.634
c0-6.425,5.209-11.634,11.634-11.634c6.425,0,11.633,5.209,11.633,11.634C31.834,26.541,26.626,31.749,20.201,31.749z" />
<path fill="#000" d="M26.013,10.047l1.654-2.866c-2.198-1.272-4.743-2.012-7.466-2.012h0v3.312h0
C22.32,8.481,24.301,9.057,26.013,10.047z">
<animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0 20 20" to="360 20 20" dur="0.5s" repeatCount="indefinite" />
</path>
</svg>
</div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoiaHVtYW5vIiwiYSI6IlgyRTFNdFEifQ.OmQBXmcVg_zq-vMpr8P5vQ';
/* var bounds = [
[-75.04728500751165, 39.68392799015035],
[-72.91058699000139, 41.87764500765852]
];*/
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/dark-v9',
center: [-72, 4],
zoom: 5,
//minZoom: 5,
//maxZoom: 5,
pitch: 40,
// maxBounds: bounds
});
<div id="map"></div>
function init() {
map.addSource('LosDatos', {
type: 'geojson',
data: './archivos/74.geojson',
//data: 'http://localhost/tupali/milfs/geojson.php?id=74',
buffer: 0,
maxzoom: 3
});
if (window.location.search.indexOf('embed') !== -1) map.scrollZoom.disable();
var url= ['get', 'title'];
map.loadImage(
// 'https://upload.wikimedia.org/wikipedia/commons/7/7c/201408_cat.png',
url,
function (error, image) {
if (error) throw error;
map.addImage('imagenIcono', image);
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoiaHVtYW5vIiwiYSI6IlgyRTFNdFEifQ.OmQBXmcVg_zq-vMpr8P5vQ';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/dark-v10',
//center: [-103.59179687498357, 40.66995747013945],
zoom: 3
});
map.on('load', function () {
/* ///gatico
var imagen = features[0].properties.imagen;
// map.loadImage('https://upload.wikimedia.org/wikipedia/commons/7/7c/201408_cat.png', function (error, image) {
map.loadImage(imagen, function (error, image) {
if (error) throw error;
map.addImage('cat', image);
}
);
*/
/* map.addLayer({
'id': 'points',
'type': 'symbol',
'source': 'earthquakes',
'layout': {
'icon-image': 'cat',
'icon-size': 0.25
}
});
*/
//fin gatico
// Add a new source from our GeoJSON data and
// set the 'cluster' option to true. GL-JS will
// add the point_count property to your source data.
map.addSource('earthquakes', {
type: 'geojson',
// Point to GeoJSON data. This example visualizes all M1.0+ earthquakes
// from 12/22/15 to 1/21/16 as logged by USGS' Earthquake hazards program.
// data: 'https://docs.mapbox.com/mapbox-gl-js/assets/earthquakes.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)
});
map.addLayer({
id: 'clusters',
type: 'circle',
source: 'earthquakes',
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: 'earthquakes',
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: 'earthquakes',
filter: ['!', ['has', 'point_count']],
paint: {
'circle-color': '#11b4da',
'circle-radius': 4,
'circle-stroke-width': 1,
'circle-stroke-color': '#fff'
}
});
// 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('earthquakes').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;
var tsunami;
if (e.features[0].properties.tsunami === 1) {
tsunami = 'yes';
} else {
tsunami = 'no';
}
// 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);
});
map.on('mouseenter', 'clusters', function () {
map.getCanvas().style.cursor = 'pointer';
});
map.on('mouseleave', 'clusters', function () {
map.getCanvas().style.cursor = '';
});
});
map.addLayer(
{
'id': 'datos-1',
'type': 'symbol',
'source': 'LosDatos',
'layout': {
// get the icon name from the source's "icon" property
// concatenate the name to get an icon from the style's sprite sheet
'icon-image': 'imagenIcono',
// get the title name from the source's "title" property
'text-field': ['get', 'title'],
'text-font': ['Open Sans Semibold', 'Arial Unicode MS Bold'],
'text-offset': [0, 0.6],
'text-anchor': 'top'
}
}
);
</script>
};
map.once('style.load', function(e) {
init();
map.addControl(new mapboxgl.NavigationControl());
map.on('click', function(e) {
var features = map.queryRenderedFeatures(e.point, {
layers: ['datos-1']
});
if (!features.length) {
return;
}
var feature = features[0];
var popup = new mapboxgl.Popup()
.setLngLat(map.unproject(e.point))
.setHTML(feature.properties.description )
.addTo(map);
});
//Hide loading bar once tiles from geojson are loaded
map.on('data', function(e) {
if (e.dataType === 'source' && e.sourceId === 'LosDatos') {
document.getElementById("loader").style.visibility = "hidden";
}
})
// Use the same approach as above to indicate that the symbols are clickable
// by changing the cursor style to 'pointer'.
map.on('mousemove', function(e) {
var features = map.queryRenderedFeatures(e.point, {
layers: ['datos-1']
});
map.getCanvas().style.cursor = (features.length) ? 'pointer' : '';
});
});
</script>
</body>
</html>