xxxxxxxxxx
<html>
<head>
<title>Map of parking meters in San Francisco, built with d3.js with leaflet.js</title>
<link
rel="stylesheet"
href="https://cdn.leafletjs.com/leaflet-0.7/leaflet.css"
/>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7/leaflet.min.js"></script>
<script src="TileLayer.Grayscale.js"></script>
</head>
<body>
<div id="map" style="width: 800px; height: 600px"></div>
<script type="text/javascript">
// ToDo: add legends to explain coloring of daata points
var c1 = ['#ccebc5', '#a8ddb5', '#7bccc4', '#4eb3d3', '#2b8cbe', '#0868ac', '#084081']
var c2 = ['#a6cee3', '#1f78b4', '#b2df8a', '#33a02c', '#fb9a99', '#fdbf6f', '#ff7f00', '#cab2d6', '#6a3d9a'];
// these palettes from from https://colorbrewer2.org/
// colors ranging from cool blue to hot red...
var c3 = ['#4575b4','#91bfdb','#e0f3f8','#ffffbf','#fee090','#fc8d59','#d73027'];
// colors ranging from icy blue to purple
var c4 = ['#edf8fb','#bfd3e6','#9ebcda','#8c96c6','#8c6bb1','#88419d','#6e016b'];
// ToDo: find better way to do this!!!!
function colors(n) {
var colors = c1;
return colors[n % colors.length];
}
var currentColoring = 0;
var currentZoom = 13; //8; //12;
mapLink =
'<a href="https://openstreetmap.org">OpenStreetMap</a>';
//-----------------------------------------------------------
// NOTE: You'll need to get your own access Token from Mapbox
// Dev account sign up is easy and free, with some dev Tokens included
// https://www.mapbox.com/help/define-access-token/
//-----------------------------------------------------------
var mbAttr = 'Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors, ' +
'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
'Imagery © <a href="https://mapbox.com">Mapbox</a>',
mbUrl = 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1Ijoia3Jpc3RpbmhlbnJ5IiwiYSI6ImNqMWdxMjd5aDAwM28zM2xtaGV2azYwcjYifQ.NTJiOqcnhP-_3etf4aZYmQ';
var grayscale = L.tileLayer(mbUrl, {id: 'mapbox.light', attribution: mbAttr}),
streets = L.tileLayer(mbUrl, {id: 'mapbox.streets', attribution: mbAttr});
var map = L.map('map', {layers: [grayscale]}).setView([37.77139, -122.44486], currentZoom);
var baseLayers = {
"Grayscale": grayscale,
"Streets": streets
};
L.control.layers(baseLayers).addTo(map);
// Add custom control for switching between dot colorings
// https://www.coffeegnome.net/control-button-leaflet/
// https://gis.stackexchange.com/questions/60576/custom-leaflet-controls
var myControl = L.Control.extend({
options: {
position: 'topright'
//control position - allowed: 'topleft', 'topright', 'bottomleft', 'bottomright'
},
onAdd: function (map) {
var container = L.DomUtil.create('div', 'leaflet-bar leaflet-control leaflet-control-custom');
L.DomEvent
.addListener(container, 'click', L.DomEvent.stopPropagation)
.addListener(container, 'click', L.DomEvent.preventDefault)
container.style.backgroundColor = 'white';
container.style.width = '30px';
container.style.height = '30px';
container.status = 0; // my own variable
container.onclick = function(){
console.log(container.status);
// might want to do this as a switch statement, if many more cases
if(container.status == 0){
container.status = 1;
} else if(container.status == 1){
container.status = 0;
}
changeColoring(container.status);
}
return container;
}
});
map.addControl(new myControl());
function changeColoring(status){
currentColoring = status;
update();
}
/* Initialize the SVG layer */
map._initPathRoot()
/* We simply pick up the SVG from the map object */
var svg = d3.select("#map").select("svg"),
g = svg.append("g");
var d3_features;
var transform;
var path;
var feature;
var ids;
var caps;
function strToLocation(s){
var arr = s.slice(1,-1).split(',');
arr[0] = parseFloat(arr[0]);
arr[1] = parseFloat(arr[1]);
return arr;
}
capColors = {
"Grey": '#999',
"Green": '#FF0',
"Yellow": 'yellow',
"Black": 'black',
"Red": 'red',
"Brown": 'brown',
"Purple": 'purple',
"Undefined": '#ccc'
}
function getCapColor(d){
return capColors[d['CAP_COLOR']];
}
// Load data and plot it on map
var datafile = "Parking_meters_sm.csv"; //"Parking_meters_sm.csv";
d3.csv(datafile, function(data){
ids = d3.map(data, function(d){return d['RATEAREA'];}).keys()
console.log(ids);
caps = d3.map(data, function(d){return d['CAP_COLOR']}).keys();
console.log(caps)
data.forEach(function(d) {
d.loc = strToLocation(d['LOCATION']);
try{
d.LatLng = new L.LatLng(d.loc[0], d.loc[1]);
} catch(err) {
console.log('error', d.LatLng, err)
}
d.color = getColor(d, ids);
var i = ids.indexOf(d['RATEAREA'])
})
feature = g.selectAll("circle")
.data(data)
.enter().append("circle")
.style("stroke", function(d){ return d.color; })
.style("opacity", .6)
.style("fill", function(d){return getFill(d) })
.attr("r", function(d){return getR(d)});
// create a d3.geo.path to convert GeoJSON to SVG
transform = d3.geo.transform({point: projectPoint});
path = d3.geo.path().projection(transform);
map.on("viewreset", update);
update();
})
function update() {
currentZoom = map.getZoom();
// reposotion dots
feature.attr("transform",
function(d) {
return "translate("+
map.latLngToLayerPoint(d.LatLng).x +","+
map.latLngToLayerPoint(d.LatLng).y +")";
})
if(currentColoring == 1){
feature.style('fill', function(d){ return getCapColor(d); })
feature.style('stroke', function(d){ return getCapColor(d); })
} else {
feature.style('fill', function(d){ return getColor(d, ids); })
feature.style('stroke', function(d){ return getColor(d, ids); })
}
// ToDo: show fewer dots when zoomed out
// // update syle of dots, according to zoom level
// if(currentZoom < 12){
// feature.style('opacity', function(d){ if(d['CAP_COLOR'] > 5){return 1;}
// else{ return .3}} )
// feature.attr('r', function(d){ if(d['CAP_COLOR'] > 5){return 2;}
// else{ return 1}} )
// } else {
// feature.style('opacity', .6);
// }
}
// Use Leaflet to implement a D3 geometric transformation.
function projectPoint(x, y) {
var point = map.latLngToLayerPoint(new L.LatLng(y, x));
this.stream.point(point.x, point.y);
}
//---------------------------------
// for popup, when map is clicked
var popup = L.popup();
function onMapClick(e) {
popup
.setLatLng(e.latlng)
.setContent("You clicked the map at " + e.latlng.toString())
.openOn(map);
}
map.on('click', onMapClick);
//---------------------------------
function createJSON(data, d_id){
var shapeJSON = {'features': [{
'type': 'Feature',
'geometry': {
'type':'Polygon',
'coordinates': data
},
'District': d_id
}]}
return shapeJSON;
}
function getR(d){
return 1;
}
function getFill(d){
return d.color;
}
function getColor(d, ids){
return colors(ids.indexOf(d['RATEAREA']))
}
</script>
</body>
</html>
Modified http://d3js.org/d3.v3.min.js to a secure url
Modified http://cdn.leafletjs.com/leaflet-0.7/leaflet.js to a secure url
https://d3js.org/d3.v3.min.js
https://cdn.leafletjs.com/leaflet-0.7/leaflet.js