|
// Default style options |
|
var geojsonMarkerOptions = { |
|
weight: 1, |
|
opacity: 1 |
|
}; |
|
|
|
// Basemaps |
|
var osm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
|
maxZoom: 19, |
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>' |
|
}); |
|
var gmaps = L.tileLayer('https://{s}.google.com/vt/lyrs=m&x={x}&y={y}&z={z}', { |
|
maxZoom: 18, |
|
subdomains: ['mt0', 'mt1', 'mt2', 'mt3'], |
|
attribution: '© Google' |
|
}); |
|
var carto = L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png', { |
|
maxZoom: 18, |
|
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, © <a href="https://carto.com/attribution"> CARTO </a>' |
|
}); |
|
var mapbox = L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', { |
|
maxZoom: 18, |
|
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' + |
|
'<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' + |
|
'Imagery © <a href="http://mapbox.com">Mapbox</a>', |
|
id: 'mapbox.streets' |
|
}); |
|
|
|
// Main variables |
|
var map = L.map('mapid', { |
|
layers: [osm] |
|
}).setView([26.924, -13.663], 7); |
|
var cluster = L.markerClusterGroup({ |
|
chunkedLoading: true |
|
}); |
|
var legend = L.control({ |
|
position: 'bottomright' |
|
}); |
|
var info = L.control({ |
|
position: 'topleft' |
|
}); |
|
var datacached; //Store a copy of the data |
|
var geojson; |
|
|
|
L.control.layers({ |
|
"OpenStreetMap": osm, |
|
"Google Maps": gmaps, |
|
"CARTO": carto, |
|
"MapBox Streets": mapbox |
|
}, null).addTo(map); |
|
|
|
// Getting data |
|
var request = new XMLHttpRequest(); |
|
request.open('GET', 'https://xavijam.carto.com/api/v2/sql?q=SELECT%20the_geom,name,adm0name,pop_max%20FROM%20ne_10m_populated_places_simple&format=GeoJSON', true); |
|
request.onload = function() { |
|
if (request.status >= 200 && request.status < 400) { |
|
// Success! |
|
datacached = JSON.parse(request.responseText); |
|
addData(datacached); |
|
|
|
} else { |
|
// We reached our target server, but it returned an error |
|
console.error('Ajax error.'); |
|
} |
|
}; |
|
request.onerror = function() { |
|
// There was a connection error of some sort |
|
}; |
|
request.send(); |
|
|
|
function addData(data) { |
|
function onEachFeature(feature, layer) { |
|
|
|
function highlightFeature(e) { |
|
|
|
info.onAdd = function(map) { |
|
this._div = L.DomUtil.create('div', 'info'); // create a div with a class "info" |
|
this.update(layer.feature.properties); |
|
return this._div; |
|
}; |
|
|
|
// method that we will use to update the control based on feature properties passed |
|
info.update = function(props) { |
|
this._div.innerHTML = '<div>' + props.name + ', ' + props.adm0name + '<br/><small>Population: ' + props.pop_max.toLocaleString() + '</small></div>'; |
|
}; |
|
|
|
info.addTo(map); |
|
} |
|
|
|
function resetHighlight(e) { |
|
info.remove(); |
|
} |
|
|
|
layer.on({ |
|
mouseover: highlightFeature, |
|
mouseout: resetHighlight |
|
}); |
|
} |
|
|
|
function pointToLayer(feature, latlng) { |
|
// Draw only what you need (that's the key) |
|
return (map.getBounds().contains(latlng)) ? L.circleMarker(latlng, geojsonMarkerOptions) : ''; |
|
} |
|
|
|
function style(feature) { |
|
if (document.getElementById("choropleth").checked) { |
|
geojsonMarkerOptions.color = getColor(feature.properties.pop_max); |
|
geojsonMarkerOptions.fillOpacity = 0.7; |
|
} |
|
return geojsonMarkerOptions; |
|
} |
|
|
|
// Remove info from map |
|
map.removeControl(info); |
|
cluster.clearLayers(); |
|
|
|
if (geojson instanceof L.GeoJSON) { |
|
map.removeLayer(geojson); |
|
} |
|
|
|
geojson = L.geoJSON((data.type === "FeatureCollection") ? data : datacached, { |
|
onEachFeature: onEachFeature, |
|
pointToLayer: pointToLayer, |
|
style: style |
|
}); |
|
|
|
// Whether user wants to clusterize |
|
if (document.getElementById("clustermarker").checked) { |
|
cluster.addLayer(geojson); |
|
} |
|
// If cluster has layers, then show them clustered, otherwise |
|
map.addLayer((cluster.getLayers().length) ? cluster : geojson); |
|
} |
|
|
|
// Global functions |
|
function getColor(d) { |
|
return d > 1000000 ? '#b30000' : |
|
d > 500000 ? '#e34a33' : |
|
d > 100000 ? '#fc8d59' : |
|
'#fdcc8a'; |
|
} |
|
|
|
// Redraw layers |
|
map.on('moveend', addData); |
|
|
|
// Clusterize listener |
|
document.getElementById("clustermarker").addEventListener('change', addData); |
|
|
|
// Listeners |
|
setListener('stroke', 'weight', 'change'); |
|
setListener('opacity', 'opacity', 'change'); |
|
setListener('fillopacity', 'fillOpacity', 'change'); |
|
setListener('colorpicker', 'color', 'change'); |
|
setListener('radius', 'radius', 'change'); |
|
|
|
function setListener(elemID, ref, event) { |
|
var elem = document.getElementById(elemID); |
|
elem.addEventListener(event, function() { |
|
geojsonMarkerOptions[ref] = elem.value; |
|
document.getElementById(elemID + "--visor").innerHTML = this.value; |
|
geojson.setStyle(geojsonMarkerOptions); |
|
}); |
|
} |
|
|
|
// Choroplethize |
|
function toggleChoropleth(cb) { |
|
|
|
var nodelist = document.querySelectorAll("input[type=range], select"); |
|
|
|
if (cb.originalTarget.checked) { |
|
|
|
// Simulates event to refresh data |
|
map.fire('moveend'); |
|
|
|
document.getElementsByClassName('palette')[0].classList.add('disabled'); |
|
for (var i = 0; i < nodelist.length; i++) { |
|
nodelist[i].disabled = true |
|
} |
|
|
|
// Create a legend |
|
legend.onAdd = function(map) { |
|
var div = L.DomUtil.create('div', 'info legend'), |
|
grades = [0, 100000, 500000, 1000000], |
|
labels = []; |
|
|
|
div.innerHTML += '<p>Marker population</p>'; |
|
// loop through our density intervals and generate a label with a colored square for each interval |
|
for (var i = 0; i < grades.length; i++) { |
|
div.innerHTML += |
|
'<i style="background:' + getColor(grades[i] + 1).toLocaleString() + '"></i> ' + |
|
grades[i].toLocaleString() + (grades[i + 1] ? '–' + grades[i + 1].toLocaleString() + '<br>' : '+'); |
|
} |
|
|
|
return div; |
|
}; |
|
legend.addTo(map); |
|
} else { |
|
// Remove legend from map |
|
map.removeControl(legend); |
|
geojson.setStyle(geojsonMarkerOptions); |
|
|
|
document.getElementsByClassName('palette')[0].classList.remove('disabled'); |
|
for (var i = 0; i < nodelist.length; i++) { |
|
nodelist[i].disabled = false; |
|
} |
|
} |
|
} |
|
document.getElementById("choropleth").addEventListener('change', toggleChoropleth); |