Skip to content

Instantly share code, notes, and snippets.

@makella
Last active August 16, 2018 17:34
Show Gist options
  • Save makella/e4886b01fd0f0090401a1400056d7761 to your computer and use it in GitHub Desktop.
Save makella/e4886b01fd0f0090401a1400056d7761 to your computer and use it in GitHub Desktop.
Active fires in the U.S. blog post
<!DOCTYPE html>
<html>
<head>
<title>Active Fires</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8">
<!-- Include CARTO VL JS -->
<script src="https://libs.cartocdn.com/carto-vl/v0.5.3/carto-vl.js"></script>
<!-- Include Mapbox GL JS -->
<script src="https://libs.cartocdn.com/mapbox-gl/v0.45.0-carto1/mapbox-gl.js"></script>
<!-- Include Mapbox GL CSS -->
<link href="https://libs.cartocdn.com/mapbox-gl/v0.45.0-carto1/mapbox-gl.css" rel="stylesheet" />
<!-- Include Roboto -->
<link href="https://fonts.googleapis.com/css?family=Roboto:400,500" rel="stylesheet">
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style-type: none;
}
#map {
position: absolute;
width: 100%;
height: 100%;
}
#date {
color: white;
font-size: 70%;
font-family: open sans;
}
#container {
color: white;
font-size: 70%;
font-family: open sans;
}
.legend {
position: absolute;
top: 32px;
left: 32px;
width: 252px;
padding: 20px;
background: #fff;
box-shadow: 0 4px 16px 0 rgba(44,44,44,0.16);
border-radius: 4px;
}
.legend-title {
font: 500 24px/32px 'Roboto';
color: #2C2C2C;
margin-bottom: 8px;
}
.legend-source {
font: 400 10px/20px 'Roboto';
color: #747474;
margin-top: 8px;
}
.legend-source a {
color: #747474;
text-decoration: underline;
}
.legend-labels {
display: flex;
}
.legend-labels li {
flex: 1;
margin-bottom: 8px;
margin-top: 12px;
}
.legend-labels li span {
height: 8px;
width: 100%;
display: block;
}
.legend-labels li:first-child span {
border-top-left-radius: 12px;
border-bottom-left-radius: 12px;
}
.legend-labels li:last-child span {
border-top-right-radius: 12px;
border-bottom-right-radius: 12px;
}
.legend-labelsExplanation {
font: 400 12px/20px 'Roboto';
color: #2C2C2C;
padding: 0 8px;
display: flex;
justify-content: space-between;
}
#date {
font: 400 14px/20px 'Roboto';
color: #2C2C2C;
text-align: center;
}
.popup-name {
font: 400 14px/20px 'Roboto';
color: #2C2C2C;
margin-bottom: 4px;
}
.popup-value {
font: 400 12px/20px 'Roboto';
color: #2C2C2C;
}
</style>
</head>
<body>
<div id="map"></div>
<div id="controls"></div>
<section class='legend'>
<h2 class='legend-title'>Active Fires in the U.S.</h2>
<p id ="date"></p>
<ul class="legend-labels">
<li>
<span style='background: linear-gradient(to bottom right, #ecda9a,#efc47e);'></span></li>
<li>
<span style='background: linear-gradient(to bottom right, #efc47e,#f3ad6a);'></span>
</li>
<li>
<span style='background: linear-gradient(to bottom right, #f3ad6a,#f7945d);'></span>
</li>
<li>
<span style='background: linear-gradient(to bottom right,#f7945d,#f97b57);'></span>
</li>
<li>
<span style='background: linear-gradient(to bottom right, #f97b57,#ee4d5a);'></span></li>
</ul>
<ul class="legend-labelsExplanation">
<li>-</li>
<li>acres burning</li>
<li>+</li>
</ul>
<p class='legend-source'>
Active <a href="https://www.geomac.gov/">fire </a> and <a href="http://satepsanone.nesdis.noaa.gov/FIRE/fire.html">smoke</a> perimeters updated daily
</p>
</section>
<script>
const map = new mapboxgl.Map({
container: 'map',
style: 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json',
center: [-114, 40],
zoom: 4.25,
scrollZoom: true,
dragRotate: false,
touchZoomRotate: false,
});
carto.setDefaultConfig({
serverURL: 'https://{user}.carto.com'
});
carto.setDefaultAuth({
user: 'mamataakella',
apiKey: 'default_public'
});
// Add first layer
const fireSource = new carto.source.SQL(`
SELECT a.*
FROM perimeters_dd83 AS a, active_perimeters_dd83 AS b
WHERE ST_Intersects(a.the_geom, b.the_geom)
ORDER BY gisacres desc
`);
const fireViz = new carto.Viz(`
@name: $firename
@acres: $gisacres
@ani: animation(linear($datecrnt,time('2018-07-01T00:00:00Z'),globalMAX($datecrnt)),30,fade(0,$gisacres))
color: opacity(ramp(linear($gisacres,viewportMIN($gisacres),viewportMAX($gisacres)),oryel),blend(0.1,0.6,linear($gisacres)))
filter: @ani + 0.02
strokeWidth: 0
`);
const fireLayer = new carto.Layer('fireLayer', fireSource, fireViz);
fireLayer.addTo(map, 'watername_ocean');
// Add second layer
const smokeSource = new carto.source.SQL(`
SELECT *
FROM hms_smoke20180727_prelim
ORDER BY density
`);
const smokeViz = new carto.Viz(`
@speed : 5*now()/$density
filter: sin(@speed)*0.5+1
color: rgba(105,105,105,0.09)
strokeWidth: 0
`);
const smokeLayer = new carto.Layer('smokeLayer', smokeSource, smokeViz);
smokeLayer.addTo(map, 'fireLayer');
// Define pop-up
const popup = new mapboxgl.Popup({
closeButton: false,
closeOnClick: false
});
// Define interactivity
const interactivity = new carto.Interactivity(fireLayer);
interactivity.on('featureHover', updatePopup);
function updatePopup(event) {
if (event.features.length) {
let maxAcres = 0;
let name = event.features[0].variables.name.value;
for (let feature of event.features) {
let acres = feature.variables.acres.value;
if (acres > maxAcres) {
maxAcres = acres;
}
}
popup.setHTML(`
<h3 class="popup-name">${name}</h3>
<p class="popup-value">${maxAcres.toFixed(2)} acres</p>
`);
popup.setLngLat([event.coordinates.lng, event.coordinates.lat]);
if (!popup.isOpen()) {
popup.addTo(map);
}
} else {
popup.remove();
}
}
// Get a reference to the date element
const $dateElement = document.querySelector('#date');
fireLayer.on('updated', () => {
let progress = fireViz.variables.ani.getProgressValue().toString();
$dateElement.innerText = progress.substring(0, 15); // Hack to get only the date
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment