Skip to content

Instantly share code, notes, and snippets.

@akanalytic
Created November 13, 2014 23:34
Show Gist options
  • Save akanalytic/e302815ce03daba459fb to your computer and use it in GitHub Desktop.
Save akanalytic/e302815ce03daba459fb to your computer and use it in GitHub Desktop.
NYC 311 Complaints around Hurricane Sandy
<!DOCTYPE html>
<html>
<head>
<title>Leaflet - NYC OpenData</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
<link href="http://netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css" rel="stylesheet">
<link rel="stylesheet" href="http://cdn.rawgit.com/lvoogdt/Leaflet.awesome-markers/2.0/develop/dist/leaflet.awesome-markers.css">
<link
//href='http://fonts.googleapis.com/css?family=Cabin:400,700|Cabin+Sketch'
href='http://fonts.googleapis.com/css?family=Amatic:400,700|Amatic+SC'
rel='stylesheet' type='text/css'>
<style>
html, body {
height: 100%;
width: 100%;
margin: 0;
}
#map {
height: 90%;
width: 100%;
}
#map_title {
height: 5%;
width: 100%;
font: 24px 'Amatic SC Regular';
}
#map_footer {
height: 5%;
width: 100%;
font: 18px 'Amatic SC Regular';
}
.leaflet-popup-content {
font-family: 'Amatic SC'}
</style>
</head>
<body>
<div id="map_title"></div>
<div id="map"></div>
<div id="map_footer"></div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<script src="https://rawgithub.com/leaflet-extras/leaflet-providers/gh-pages/leaflet-providers.js"></script>
<script src="http://cdn.rawgit.com/lvoogdt/Leaflet.awesome-markers/2.0/develop/dist/leaflet.awesome-markers.min.js"></script>
<script src="http://cdn.rawgit.com/jseppi/Leaflet.MakiMarkers/master/Leaflet.MakiMarkers.js"></script>
<script>
var zoom = 12; //set zoom level here
var center = [40.658528, -73.952551]; //set center coordinates here [latitude, longitude]
var map = L.map('map').setView(center, zoom);
//declare base map provider
//http://leaflet-extras.github.io/leaflet-providers/preview/
//var provider_name = "OpenStreetMap.Mapnik, OpenWeatherMap.Rain"; //provider name goes here
var provider_name = "Stamen.Terrain"; //provider name goes here
//add provider tile layer to map
L.tileLayer.provider(provider_name).addTo(map);
map.attributionControl.setPrefix('311 Complaints : NYC OpenData'); //add data source to map's attribute text
//map.attributionControl.setPrefix('DOHMH New York City Restaurant Inspection Results'); //add data source to map's attribute text
//data URL variables
var start_date = '2012-10-29'; //YYYY-MM-DD
var end_date = '2012-10-31'; //YYYY-MM-DD
var borough = 'QUEENS';
var c_type1 = 'Water System'; //complaint type 1
var c_type2 = 'Heating'; //complaint type 2
$( "#map_title" ).html( c_type1 + " and " + c_type2 + " 311 Service Requests from Hurricane Sandy between " + start_date + " and " + end_date);
$( "#map_footer" ).html( "Map By: Alice Roberts, Lehman College - Geovisualization and Analytical Cartography (G. Culp, Fall 2014)");
//i didn't like any of the icons here, so I'm using leaflet for both of my complaint types.
//define marker icon using Leaflet Maki Markers
//(https://github.com/jseppi/Leaflet.MakiMarkers)
//var c_type1_icon = L.MakiMarkers.icon({
// icon: "", //https://www.mapbox.com/maki/
// color: "#FF3300", //any hex color (e.g., "#FFFFFF")
// size: "l", //['s','m','l']
// iconSize: [20, 50]
//});
//define marker icon using Leaflet Awesome
//(https://github.com/lvoogdt/Leaflet.awesome-markers)
//markerColor options : //['red','darkred','lightred','orange',
//'beige','green','darkgreen','lightgreen','blue','darkblue',
//'lightblue','purple','darkpurple','pink','cadetblue','white',
//'gray','lightgray','black']
//browse icons: http://fortawesome.github.io/Font-Awesome/icons/
var c_type1_icon = L.AwesomeMarkers.icon({
icon: 'tint',
prefix: 'fa',
markerColor: 'darkblue',
iconColor: '#ffffff' //any hex color (e.g., "#FFFFFF")
});
var c_type2_icon = L.AwesomeMarkers.icon({
icon: 'fire',
prefix: 'fa',
markerColor: 'darkred',
iconColor: '#CC3300' //any hex color (e.g., "#FFFFFF")
});
//build the data URL
var URL = "http://data.cityofnewyork.us/resource/erm2-nwe9.json"; //API Access Endpoint
URL += "?"; //a query parameter name is preceded by the question mark
URL += "$where="; //Filters the rows to be returned
URL += "(latitude IS NOT NULL)"; //only return records with coordinates
//URL += " AND ";
//URL += "(borough='" + borough + "')"; //borough of interest
URL += " AND ";
URL += "((complaint_type='" + c_type1 + "') OR (complaint_type='" + c_type2 + "'))"; //desired two complaint types nested within parentheses
URL += " AND ";
URL += "(created_date>='" + start_date + "') AND (created_date<='" + end_date + "')"; //date range
URL += "&$group=complaint_type,latitude,longitude"; //fields to group by
URL += "&$select=complaint_type,latitude,longitude,count(*)"; //fields to return
URL = encodeURI(URL); //encode special characters such as spaces and quotes
$.getJSON(URL, function (data) {
//console.log(data.length); //the record limit is 1000 so if you get 1000 scale down your date range
var c_type1_markers = []; //array to store c_type1 markers
var c_type2_markers = []; //array to store c_type2 markers
var all_markers = []; //array to store all markers
//iterate through records
$.each(data, function(index, rec){
//build html string from fields
var popup_html = "<b>" + rec.complaint_type + "</b>";
popup_html += "<br>";
popup_html += rec.count + " complaint(s) at this location";
var marker;
if (rec.complaint_type==c_type1) {
marker = L.marker([rec.latitude, rec.longitude], { icon: c_type1_icon }).bindPopup(popup_html);
c_type1_markers.push(marker); //add marker to array of c_type1 markers
}
else {
marker = L.marker([rec.latitude, rec.longitude], { icon: c_type2_icon }).bindPopup(popup_html);
c_type2_markers.push(marker); //add marker to array of c_type2 markers
}
all_markers.push(marker); //add marker to array of all markers
});
var all_layer = L.featureGroup(all_markers); //create layer of all markers but do not add to map
var c_type1_layer = L.featureGroup(c_type1_markers).addTo(map); //create layer of c_type1 markers and add to map
var c_type2_layer = L.featureGroup(c_type2_markers).addTo(map); //create layer of c_type2 markers and add to map
map.fitBounds(all_layer.getBounds()); //use layer of all markers to set map extent
//create object containing c_type1 and c_type2 marker layers
var overlays = {};
overlays[c_type1] = c_type1_layer;
overlays[c_type2] = c_type2_layer;
//add layer control using above object
L.control.layers(null,overlays).addTo(map);
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment