Skip to content

Instantly share code, notes, and snippets.

@wboykinm
Last active August 29, 2015 13:56
Show Gist options
  • Save wboykinm/9035841 to your computer and use it in GitHub Desktop.
Save wboykinm/9035841 to your computer and use it in GitHub Desktop.
Leaflet Vectors and Nested Functions, Oh My!
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Sacramento Tree Foundation Map</title>
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' />
<link href='https://api.tiles.mapbox.com/mapbox.js/v1.6.1/mapbox.css' rel='stylesheet' />
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Rokkitt:400,700" />
<link href='style.css' rel='stylesheet' />
</head>
<body>
<ul id='map-ui'>
<li><a id="Percent_TC" class="lyr tree">% Tree Canopy</a></li>
<li><a id="mean_bmi" class="lyr health">Mean BMI</a></li>
<li><a id="per_ovw_ob" class="lyr health">% Overweight or Obese</a></li>
<li><a id="per_ob" class="lyr health">% Obese</a></li>
<li><a id="per_mvpa" class="lyr health active">% w/ >150min MVPA/wk</a></li>
<li><a id="per_hi_bp" class="lyr health">% w/ High Blood Pressure</a></li>
<li><a id="per_type2" class="lyr health">% w/ Type 2 Diabetes</a></li>
<li><a id="per_frpr" class="lyr health">% in Fair/Poor health</a></li>
<li><a id="per_asthma" class="lyr health">% w/ Asthma</a></li>
</ul>
<div id='map'></div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src='http://api.tiles.mapbox.com/mapbox.js/v1.6.1/mapbox.js'></script>
<script src='//api.tiles.mapbox.com/mapbox.js/plugins/leaflet-hash/v0.2.1/leaflet-hash.js'></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script>
var mapdataviz,
popup,
zips_geojson,
zipsLayer;
// Creat wrapper function
$(function() {
// Create Data loading function, repeatable on page load and on button click
var loadData = function() {
// Create map
mapdataviz = L.mapbox.map('map', 'landplanner.map-khn9uycz').setView([38.574, -121.384], 10);
// Create Popup
popup = new L.Popup({
autoPan: false
});
var hash = L.hash(mapdataviz);
// ADD THE REFERENCE OVERLAY
var topPane = mapdataviz._createPane('leaflet-top-pane', mapdataviz.getPanes().mapPane);
var topLayer = new L.mapbox.tileLayer('sactree.h7id69df', {
maxZoom: 17,
opacity: 0.4
}).addTo(mapdataviz);
topPane.appendChild(topLayer.getContainer());
topLayer.setZIndex(7);
// Add and define the variables that carry theme info to the layer constructor
var actVar = $('a.active').attr('id');
var actLayer = 'layer.feature.properties.' + actVar;
var actFeature = 'feature.properties.' + actVar;
//Get the topojson
$.getJSON('sactree_zips.json', function(data) {
console.log('json loaded!')
// Convert the topojson to geojson
zips_geojson = topojson.feature(data, data.objects.zips).features;
// Create leaflet vector layer and add it to the map
zipsLayer = L.geoJson(zips_geojson, {
style: getStyle,
onEachFeature: onEachFeature
}).addTo(mapdataviz);
// Define the vector styles
function getStyle(feature) {
return {
weight: 1,
opacity: 0.2,
color: 'black',
fillOpacity: 0.95,
fillColor: getColor(eval(actFeature))
};
}
// Define the polygon fill, conditional on theme and value
function getColor(d) {
if (actVar == 'Percent_TC') {
return d > 33 ? '#588125'
: d > 23 ? '#729B3F'
: d > 15 ? '#8BB458'
: d > 9 ? '#A5CE72'
: d > 4 ? '#BEE78B'
: d > 0.5 ? '#D7FFA4'
: '#fff';
}
if (actVar == 'mean_bmi') {
return d > 31 ? '#4b75b3'
: d > 29 ? '#523494'
: d > 27 ? '#99a9c6'
: d > 25 ? '#bcc5cf'
: d > 22 ? '#dde1d8'
: d > 20 ? '#ffffe0'
: '#fff';
}
else {
return d > 0.7 ? '#4b75b3'
: d > 0.5 ? '#523494'
: d > 0.4 ? '#99a9c6'
: d > 0.25 ? '#bcc5cf'
: d > 0.1 ? '#dde1d8'
: d > 0.02 ? '#ffffe0'
: '#fff';
}
}
// Define the interactivity
function onEachFeature(feature, layer) {
layer.on({
mousemove: mousemove,
mouseout: mouseout,
click: zoomToFeature
});
}
var closeTooltip;
// Define the popup content, also conditional on theme and value
function mousemove(e) {
var layer = e.target;
popup.setLatLng(e.latlng);
if (actVar == 'Percent_TC' || actVar == 'mean_bmi') {
popup.setContent('<div class="marker-title">' + layer.feature.properties.NAME + ' - ' + layer.feature.properties.ID + '</div>' + $('.active').text() + ": <b>" + Math.round(eval(actLayer)).toFixed(0) + "</b>");
}
else {
popup.setContent('<div class="marker-title">' + layer.feature.properties.NAME + ' - ' + layer.feature.properties.ID + '</div>' + Math.round(eval(actLayer) * 100).toFixed(0) + $('.active').text());
}
if (!popup._map) popup.openOn(mapdataviz);
window.clearTimeout(closeTooltip);
// highlight feature on mouseover
layer.setStyle({
weight: 3,
opacity: 0.3,
fillOpacity: 0.3
});
if (!L.Browser.ie && !L.Browser.opera) {
layer.bringToFront();
}
}
function mouseout(e) {
zipsLayer.resetStyle(e.target);
closeTooltip = window.setTimeout(function() {
mapdataviz.closePopup();
}, 100);
}
function zoomToFeature(e) {
mapdataviz.fitBounds(e.target.getBounds());
}
});
};
// Define the reload-on-click function
$('.lyr').click(function () {
$('.lyr').removeClass('active');
// todo - remove old polygons before reload:
mapdataviz.removeLayer(zipsLayer);
$(this).addClass('active');
// Redefine the theme variables based on the clicked button
actVar = $(this).attr('id');
actLayer = 'layer.feature.properties.' + actVar;
actFeature = 'feature.properties.' + actVar;
// Fire the big data loading function
loadData();
});
// init
loadData();
});
</script>
</body>
</html>
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
body {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: normal 18px/25px 'Rokkitt', Georgia, serif;
vertical-align: baseline;
}
#map { position:absolute; top:0; bottom:0; width:100%; }
.map-legend .swatch {
width:20px;
height:20px;
float:left;
margin-right:10px;
}
.leaflet-popup-close-button {
display: none;
}
.leaflet-popup-content-wrapper {
pointer-events: none;
}
.leaflet-top-pane {
pointer-events: none;
}
#map-ui {
position: absolute;
top: 15px;
right: 10px;
list-style: none;
margin: 0;
padding: 10px;
z-index: 100;
background-color: rgba(255,255,255,0.8);
border: 2px solid #BBB;
}
#map-ui a {
color: #E5EFD4;
display: block;
margin: 0;
padding: 0;
border-radius: 6px;
min-width: 105px;
padding: 10px;
text-decoration: none;
text-transform: uppercase;
text-align: center;
border: 1px solid #fff;
}
#map-ui a.tree {
background-color: #729B3F;
}
#map-ui a.health {
background-color: #4B75B3;
}
#map-ui a:hover {
opacity: 0.8;
filter: alpha(opacity=80);
border-color: #FFF;
}
#map-ui a.active {
opacity: 0.6;
filter: alpha(opacity=60);
border: 2px solid #333;
color: #fff;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment