|
<!DOCTYPE html> |
|
<html> |
|
|
|
<head> |
|
<meta charset='utf-8' /> |
|
<title></title> |
|
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' /> |
|
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.54.0-beta.1/mapbox-gl.js'></script> |
|
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.54.0-beta.1/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 */ |
|
|
|
.mapboxgl-popup-content { |
|
background-color: #202020; |
|
color: #fff; |
|
margin-left: 5px; |
|
margin-top: 2px; |
|
margin-bottom: 2px; |
|
margin-right: 5px; |
|
z-index: 1000; |
|
} |
|
|
|
.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> |
|
</head> |
|
|
|
<body> |
|
<div id='map'></div> |
|
<div class='map-overlay top'> |
|
<div class='map-overlay-inner'> |
|
<fieldset> |
|
<label><b>Select property</b></label> |
|
<select id='prop' name='prop'> |
|
<option value='CYC_INJ'>Cyclist Injuries</option> |
|
<option value='CYC_KIL'>Cyclist Fatalities</option> |
|
<option value='PED_INJ'>Pedestrian Injuries</option> |
|
<option value='PED_KIL'>Pedestrian Fatalities</option> |
|
</select> |
|
</fieldset> |
|
<b><a href="https://data.cityofnewyork.us/Public-Safety/NYPD-Motor-Vehicle-Collisions/h9gi-nx95" target="_blank">NYC Open Data</a></b> |
|
</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.eyJ1IjoicnNiYXVtYW5uIiwiYSI6ImNqNmhkZnhkZDA4M3Yyd3AwZDR4cmdhcDIifQ.TGKKAC6pPP0L-uMDJ5xFAA'; |
|
var bounds = [ |
|
[-75.04728500751165, 39.68392799015035], |
|
[-72.91058699000139, 41.87764500765852] |
|
]; |
|
var map = new mapboxgl.Map({ |
|
container: 'map', |
|
style: 'mapbox://styles/mapbox/dark-v9', |
|
center: [-74.0059, 40.7128], |
|
zoom: 10, |
|
minZoom: 9, |
|
maxZoom: 18, |
|
pitch: 40, |
|
maxBounds: bounds |
|
}); |
|
|
|
function init() { |
|
map.addSource('veh-incidents-1', { |
|
type: 'geojson', |
|
data: 'https://dl.dropbox.com/s/z4hajzr32e59kv4/nyc_pedcyc_collisions_1.geojson?dl=0', |
|
buffer: 0, |
|
maxzoom: 12 |
|
}); |
|
|
|
map.addSource('veh-incidents-2', { |
|
type: 'geojson', |
|
data: 'https://dl.dropbox.com/s/prxhl4whif6tstt/nyc_pedcyc_collisions_2.geojson?dl=0', |
|
buffer: 0, |
|
maxzoom: 12 |
|
}); |
|
|
|
if (window.location.search.indexOf('embed') !== -1) map.scrollZoom.disable(); |
|
|
|
map.addLayer({ |
|
'id': 'veh-incd-1', |
|
'type': 'circle', |
|
'source': 'veh-incidents-1', |
|
'paint': { |
|
'circle-color': { |
|
property: 'CYC_INJ', |
|
type: 'interval', |
|
stops: [ |
|
[1, 'orange'], |
|
[2, 'red'] |
|
] |
|
}, |
|
'circle-radius': { |
|
property: 'CYC_INJ', |
|
base: 3, |
|
type: 'interval', |
|
stops: [ |
|
[1, 3], |
|
[2, 8], |
|
[3, 12] |
|
] |
|
}, |
|
'circle-opacity': 0.8, |
|
'circle-blur': 0.5 |
|
}, |
|
'filter': ['>=', 'CYC_INJ', 1] |
|
}, 'waterway-label'); |
|
|
|
map.addLayer({ |
|
'id': 'veh-incd-2', |
|
'type': 'circle', |
|
'source': 'veh-incidents-2', |
|
'paint': { |
|
'circle-color': { |
|
property: 'CYC_INJ', |
|
type: 'interval', |
|
stops: [ |
|
[1, 'orange'], |
|
[2, 'red'] |
|
] |
|
}, |
|
'circle-radius': { |
|
property: 'CYC_INJ', |
|
base: 3, |
|
type: 'interval', |
|
stops: [ |
|
[1, 3], |
|
[2, 8], |
|
[3, 12] |
|
] |
|
}, |
|
'circle-opacity': 0.8, |
|
'circle-blur': 0.5 |
|
}, |
|
'filter': ['>=', 'CYC_INJ', 1] |
|
}, 'waterway-label'); |
|
|
|
map.addLayer({ |
|
'id': 'veh-incd-base-1', |
|
'type': 'circle', |
|
'source': 'veh-incidents-1', |
|
'paint': { |
|
'circle-color': 'yellow', |
|
'circle-radius': 3, |
|
'circle-opacity': 0.3, |
|
'circle-blur': 1 |
|
}, |
|
'filter': ['<', 'CYC_INJ', 1] |
|
}, 'waterway-label'); |
|
|
|
map.addLayer({ |
|
'id': 'veh-incd-base-2', |
|
'type': 'circle', |
|
'source': 'veh-incidents-2', |
|
'paint': { |
|
'circle-color': 'yellow', |
|
'circle-radius': 3, |
|
'circle-opacity': 0.3, |
|
'circle-blur': 1 |
|
}, |
|
'filter': ['<', 'CYC_INJ', 1] |
|
}, 'waterway-label'); |
|
}; |
|
|
|
map.once('style.load', function(e) { |
|
init(); |
|
map.addControl(new mapboxgl.NavigationControl()); |
|
map.on('click', function(e) { |
|
var features = map.queryRenderedFeatures(e.point, { |
|
layers: ['veh-incd-1', 'veh-incd-2'] |
|
}); |
|
if (!features.length) { |
|
return; |
|
} |
|
var feature = features[0]; |
|
|
|
var popup = new mapboxgl.Popup() |
|
.setLngLat(map.unproject(e.point)) |
|
.setHTML('<h3>Collision Detail</h3>' + |
|
'<ul>' + |
|
'<li>Year: <b>' + feature.properties.YEAR + '</b></li>' + |
|
'<li>Pedestrian Injuries: <b>' + feature.properties.PED_INJ + '</b></li>' + |
|
'<li>Pedestrian Fatalities: <b>' + feature.properties.PED_KIL + '</b></li>' + |
|
'<li>Cyclist Injuries: <b>' + feature.properties.CYC_INJ + '</b></li>' + |
|
'<li>Cyclist Fatalities: <b>' + feature.properties.CYC_KIL + '</b></li>' + |
|
'</ul>') |
|
.addTo(map); |
|
}); |
|
|
|
//Hide loading bar once tiles from geojson are loaded |
|
map.on('data', function(e) { |
|
if (e.dataType === 'source' && e.sourceId === 'veh-incidents-1') { |
|
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: ['veh-incd-1', 'veh-incd-2'] |
|
}); |
|
map.getCanvas().style.cursor = (features.length) ? 'pointer' : ''; |
|
}); |
|
var prop = document.getElementById('prop'); |
|
prop.addEventListener('change', function() { |
|
map.setPaintProperty('veh-incd-1', 'circle-color', { |
|
property: prop.value, |
|
type: 'interval', |
|
stops: [ |
|
[1, 'orange'], |
|
[2, 'red'] |
|
] |
|
}); |
|
map.setPaintProperty('veh-incd-2', 'circle-color', { |
|
property: prop.value, |
|
type: 'interval', |
|
stops: [ |
|
[1, 'orange'], |
|
[2, 'red'] |
|
] |
|
}); |
|
map.setPaintProperty('veh-incd-1', 'circle-radius', { |
|
property: prop.value, |
|
base: 3, |
|
type: 'interval', |
|
stops: [ |
|
[1, 3], |
|
[2, 6], |
|
[3, 9] |
|
] |
|
}); |
|
map.setPaintProperty('veh-incd-2', 'circle-radius', { |
|
property: prop.value, |
|
base: 3, |
|
type: 'interval', |
|
stops: [ |
|
[1, 3], |
|
[2, 6], |
|
[3, 9] |
|
] |
|
}); |
|
map.setFilter('veh-incd-1', ['>=', prop.value, 1]) |
|
map.setFilter('veh-incd-2', ['>=', prop.value, 1]) |
|
}); |
|
}); |
|
</script> |
|
</body> |
|
|
|
</html> |