|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<title>Pune Info</title> |
|
<meta charset="utf-8" /> |
|
<link rel="stylesheet" href="lib/leaflet.css" /> <!-- original: http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css --> |
|
<link rel="stylesheet" href="lib/leaflet-search.css" /> |
|
<link rel="stylesheet" href="lib/leaflet-measure.css"> |
|
<link rel="stylesheet" href="lib/leaflet.label.css"> |
|
<link rel="stylesheet" href="lib/Control.FullScreen.css" /> |
|
<link rel="stylesheet" href="lib/MarkerCluster.Default.css" /> |
|
<link rel="stylesheet" href="lib/MarkerCluster.css" /> |
|
|
|
</head> |
|
<style> |
|
html, body, #container, #map { |
|
padding: 0; |
|
margin: 0; |
|
} |
|
html, body, #map, #container { |
|
height: 100%; |
|
} |
|
#sidepanel { |
|
height: 90%; |
|
} |
|
.info { |
|
padding: 6px 8px; |
|
font: 14px/16px Calibri, Arial, Helvetica, sans-serif; |
|
background: white; |
|
background: rgba(255,255,255,0.8); |
|
box-shadow: 0 0 15px rgba(0,0,0,0.2); |
|
border-radius: 5px; |
|
width: 400px; |
|
} |
|
.info h4 { |
|
margin: 0 0 5px; |
|
color: #777; |
|
} |
|
|
|
.leaflet-google-layer { |
|
z-index: 0 !important; |
|
} |
|
|
|
//.leaflet-map-pane { |
|
// z-index: 100; |
|
/* This is for google maps */ |
|
//} |
|
|
|
#container { |
|
// position: relative; |
|
} |
|
#map { |
|
display:inline-block; |
|
width: 100%; |
|
} |
|
|
|
#sidepanel { |
|
padding-top: 35px; |
|
padding-bottom: 25px; |
|
padding-left: 15px; |
|
width: 25%; |
|
min-width: 200px; |
|
position: absolute; |
|
z-index: 10; |
|
font: 14px Calibri, Arial, Helvetica, sans-serif; |
|
overflow: auto; |
|
//background: -webkit-linear-gradient(left, rgba(153,189,188,0), rgba(153,189,188,1)); /* For Safari 5.1 to 6.0 */ |
|
//background: -o-linear-gradient(right, rgba(153,189,188,0), rgba(153,189,188,1)); /* For Opera 11.1 to 12.0 */ |
|
//background: -moz-linear-gradient(right, rgba(153,189,188,0), rgba(153,189,188,1)); /* For Firefox 3.6 to 15 */ |
|
//background: linear-gradient(to left, rgba(153,189,188,0), rgba(153,189,188,1)); /* Standard syntax (must be last) */ |
|
//background: linear-gradient(to left, rgba(248, 227, 190,0), rgba(248, 227, 190,1)); /* Standard syntax (must be last) */ |
|
|
|
// from http://www.colorzilla.com/gradient-editor/ |
|
background: -moz-linear-gradient(left, rgba(255,255,255,1) 0%, rgba(255,255,255,0.8) 60%, rgba(255,255,255,0) 100%); /* FF3.6+ */ |
|
background: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(255,255,255,1)), color-stop(60%,rgba(255,255,255,0.8)), color-stop(100%,rgba(255,255,255,0))); /* Chrome,Safari4+ */ |
|
background: -webkit-linear-gradient(left, rgba(255,255,255,1) 0%,rgba(255,255,255,0.8) 60%,rgba(255,255,255,0) 100%); /* Chrome10+,Safari5.1+ */ |
|
background: -o-linear-gradient(left, rgba(255,255,255,1) 0%,rgba(255,255,255,0.8) 60%,rgba(255,255,255,0) 100%); /* Opera 11.10+ */ |
|
background: -ms-linear-gradient(left, rgba(255,255,255,1) 0%,rgba(255,255,255,0.8) 60%,rgba(255,255,255,0) 100%); /* IE10+ */ |
|
background: linear-gradient(to right, rgba(255,255,255,1) 0%,rgba(255,255,255,0.8) 60%,rgba(255,255,255,0) 100%); /* W3C */ |
|
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#00ffffff',GradientType=1 ); /* IE6-9 */ |
|
|
|
|
|
} |
|
#sidepanel h4 { |
|
margin: 40px 0 5px; |
|
padding-left: 35px; |
|
font: 20px Calibri, Arial, Helvetica, sans-serif; |
|
} |
|
|
|
</style> |
|
<body> |
|
<div id="container"> |
|
<div id="sidepanel"> |
|
<h4>Pune Info</h4>Click on an item to see its details. |
|
</div> |
|
<div id="map"></div> |
|
</div> |
|
<script src="lib/leaflet.js"></script> <!-- Orginal: http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js --> |
|
<script src="lib/leaflet-search.js"></script> <!-- from http://labs.easyblog.it/maps/leaflet-search/examples/nominatim.html --> |
|
<script src="lib/leaflet-measure.js"></script> <!-- from https://github.com/ljagis/leaflet-measure --> |
|
<script src='lib/leaflet-omnivore.min.js'></script> <!--Original: https://api.tiles.mapbox.com/mapbox.js/plugins/leaflet-omnivore/v0.2.0/leaflet-omnivore.min.js --> |
|
<script src="lib/leaflet.label.js"></script> <!-- from https://github.com/Leaflet/Leaflet.label --> |
|
<script src="lib/papaparse.min.js"></script> <!-- from http://papaparse.com --> |
|
<!-- Scripts for Google maps layer,taken from http://bl.ocks.org/crofty/2197701 --> |
|
<!-- <script src="http://maps.google.com/maps/api/js?v=3.2&sensor=false"></script> Don't want to depend on google right now..--> |
|
<script src="lib/leaflet-google.js"></script> <!--Original: http://matchingnotes.com/javascripts/leaflet-google.js --> |
|
<script src="lib/Control.FullScreen.js"></script> <!-- From https://github.com/brunob/leaflet.fullscreen --> |
|
<script src="lib/turf.min.js"> </script> <!-- from http://api.tiles.mapbox.com/mapbox.js/plugins/turf/v2.0.0/turf.min.js --> |
|
<script src="lib/leaflet.markercluster-src.js"> </script> <!-- from http://api.tiles.mapbox.com/mapbox.js/plugins/turf/v2.0.0/turf.min.js --> |
|
|
|
<script> |
|
var DATAPATH = "data/" |
|
var PICSPATH = DATAPATH + 'ER_pics/'; |
|
var SidePanelDefault = "<h4>Pune Info</h4>Click on an item to see its details."; |
|
|
|
var osmLink = '<a href="http://openstreetmap.org">OpenStreetMap</a>'; |
|
var mapboxUrl = 'https://{s}.tiles.mapbox.com/v3/{id}/{z}/{x}/{y}.png'; |
|
var MBAttrib = '© ' + osmLink + ' Contributors & <a href="https://www.mapbox.com/about/maps/">Mapbox</a>'; |
|
|
|
var MBstreets = L.tileLayer(mapboxUrl, {id: 'nikhilsheth.m0mlpl2d', attribution: MBAttrib}), |
|
MBsatlabel = L.tileLayer(mapboxUrl, {id: 'nikhilsheth.m0mmaa87', attribution: MBAttrib}), |
|
MBsat = L.tileLayer(mapboxUrl, {id: 'nikhilsheth.m0mni8e7', attribution: MBAttrib}), |
|
MBemerald = L.tileLayer(mapboxUrl, {id: 'nikhilsheth.m0mmebk6', attribution: MBAttrib}), |
|
MBrun = L.tileLayer(mapboxUrl, {id: 'nikhilsheth.m0mmicn2', attribution: MBAttrib}), |
|
MBlight = L.tileLayer(mapboxUrl, {id: 'nikhilsheth.m0mmobne', attribution: MBAttrib}), |
|
MBbw = L.tileLayer(mapboxUrl, {id: 'nikhilsheth.m0mn13df', attribution: MBAttrib}), |
|
MBdark = L.tileLayer(mapboxUrl, {id: 'nikhilsheth.jme9hi44', attribution: MBAttrib}), |
|
MBpencil = L.tileLayer(mapboxUrl, {id: 'nikhilsheth.m0mn5lf5', attribution: MBAttrib}), |
|
MBpirates = L.tileLayer(mapboxUrl, {id: 'nikhilsheth.m0mn8b72', attribution: MBAttrib}), |
|
MBwheatpaste = L.tileLayer(mapboxUrl, {id: 'nikhilsheth.m0mnld61', attribution: MBAttrib}), |
|
MBcomic = L.tileLayer(mapboxUrl, {id: 'nikhilsheth.m0mo16hg', attribution: MBAttrib}), |
|
|
|
OsmIndia = L.tileLayer(mapboxUrl, {id: 'openstreetmap.1b68f018', attribution: MBAttrib}); |
|
|
|
var baseLayers = { |
|
"OpenStreetMap.IN": OsmIndia, |
|
// "OpenStreetMap": osmMap, |
|
// "OSM Landscape": landMap, |
|
// "Stamen Toner": stamentoner, |
|
// "Stamen Toner-Lite": stamenlite, |
|
// "Stamen Toner-Hybrid": stamenhybid, |
|
// "Stamen Toner-Labels": stamenlabels, |
|
// "Stamen Toner-Lines": stamenlines, |
|
// "Watercolor": stamenwater, |
|
"Mapbox Streets": MBstreets, |
|
"Mapbox Satellite w/labels": MBsatlabel , |
|
// "Mapbox Satellite": MBsat , |
|
// "Mapbox Emerald": MBemerald , |
|
// "Mapbox Run,Cycle": MBrun , |
|
"Mapbox Light": MBlight , |
|
// "Mapbox Black and White": MBbw , |
|
"Mapbox Dark": MBdark , |
|
"Mapbox Pencil": MBpencil , |
|
// "Mapbox Pirates": MBpirates , |
|
// "Mapbox Wheatpaste": MBwheatpaste , |
|
// "Mapbox Comic": MBcomic , |
|
// "Google Maps": googleLayer |
|
}; |
|
|
|
var map = L.map('map', { |
|
layers: [OsmIndia], //only add one! put the rest in the baselayers group |
|
fullscreenControl: true, |
|
fullscreenControlOptions: { |
|
position: 'topleft' |
|
} |
|
}) |
|
.setView([18.53,73.85], 12) |
|
.on('overlayremove', function(e) { // to reset the side panel |
|
document.getElementById('sidepanel').innerHTML = SidePanelDefault; |
|
}); |
|
|
|
|
|
var wards = defaultArea().addTo(map); // Initializing and Pre-loading initial/default overlay |
|
|
|
var overlays = { |
|
"Electoral Wards": wards |
|
}; |
|
var layerControl = L.control.layers(baseLayers, overlays, {collapsed: false}).addTo(map); |
|
//making a variable of the layer control, so we can dynamically add new layers later on. From http://stackoverflow.com/a/25385141/4355695 |
|
|
|
|
|
//################################################################# |
|
// ELECTORAL WARDS ... SYNC'D WITH INFO CSV |
|
//omnivore.geojson(DATAPATH+'pune-electoral-wards.geojson', null, wards); |
|
//so basically we added this layer to the main map as an empty (but initialized) one and then later loaded it up with data, and that's OK! |
|
Papa.parse(DATAPATH + 'pune-wards-info.csv', { |
|
download: true, |
|
header: true, |
|
complete: function(results) { |
|
var PuneInfoLayer = L.geoJson(null, { |
|
style: {weight: 2, opacity: 1, color: 'black', dashArray: '4', fillOpacity: 0.2, fillColor: "orange" }, |
|
onEachFeature: function(feature, layer) { //below code will be executed for each item in the layer |
|
;var popupText = ""; |
|
var labelText = ""; |
|
var detailsText = ""; |
|
if (feature.properties && feature.properties.name && turf.area(feature)) { |
|
//Here it comes! The part where we look up the CSV data for a row having the same name as the map item's name |
|
labelText = feature.properties.name.toString(); |
|
var filtered = results.data.filter(function(data){return data.name == this;}, labelText); |
|
detailsText = "<h4>" + labelText + ' : ' + filtered[0]['title'] + "</h4>"; |
|
labelText += ' : ' + filtered[0]['title']; |
|
//console.log(JSON.stringify(filtered[0])); |
|
detailsText += 'Admin ward: <b>' + filtered[0]['adminward'] + '</b><br><br>'; |
|
detailsText += '<b>Voters:</b> ' + filtered[0]['voters'] + ', ' + filtered[0]['female_voters'] + ' female, ' + filtered[0]['male_voters'] + ' male<br><br>'; |
|
detailsText += '<b>Elected Representatives:</b><br><table cellspacing="20">'; |
|
detailsText+= '<tr><td><img src="'+ PICSPATH + filtered[0]['wardnum'] +'A.jpg" height="100px"><br>A: ' + filtered[0]['ER_A'] + '</td><td><img src="'+ PICSPATH + filtered[0]['wardnum'] +'B.jpg" height="100px"><br>B: ' + filtered[0]['ER_B'] + '</td></tr></table>'; |
|
detailsText += 'Municipal Polling Stations: <b>' + filtered[0]['total_polling_buildings'] + '</b> buildings, <b>' + filtered[0]['total_polling_stations'] + '</b> stations.<br><br>'; |
|
detailsText += '<b>Area:</b> ' + Math.round(turf.area(feature)*(1e-6)*100)/100 + ' sq.km <br>'; |
|
detailsText += '<small><b>Areas / Landmarks : </b>' + filtered[0]['areas'] + '</small>'; |
|
} |
|
layer.bindLabel(labelText); //removing .bindPopup(detailsText); |
|
layer.on({ |
|
click: function() { |
|
document.getElementById('sidepanel').innerHTML = detailsText; |
|
} |
|
}); |
|
} //end onEachFeature |
|
}); //end layer defining. We still have to load the data into it!! |
|
|
|
omnivore.geojson(DATAPATH+'pune-electoral-wards.geojson', null, PuneInfoLayer).addTo(wards); |
|
} //Papa.parse's complete: section over |
|
}); // Papa.parse function over. |
|
|
|
|
|
|
|
|
|
|
|
//#### NOW ADD MORE LAYERS ####### |
|
|
|
//GARDENS |
|
var gardenslayer = circleMarker("green","Gardens in Pune"); |
|
omnivore.csv('http://cors.io/?u=https://docs.google.com/spreadsheets/d/1Ec3Yegt1fIOTpyUv8DcLBsVFlu1P1ibGtQfTV4rU13w/export?format=csv', null, gardenslayer) |
|
.on('error', function() { |
|
// fired if the layer can't be loaded over AJAX |
|
// or can't be parsed |
|
console.log("HEY! ERROR WHILE LOADING GARDENS!"); |
|
}); |
|
//backup CSV path: DATAPATH+'pune_gardens.csv' |
|
layerControl.addOverlay(gardenslayer , "Gardens"); |
|
|
|
//SCHOOLS |
|
var schoolslayer = circleMarker("blue","Government Schools",["name","School_No"]); |
|
omnivore.csv(DATAPATH+'pune-school-locations.csv', null, schoolslayer); |
|
layerControl.addOverlay(schoolslayer , "Schools"); |
|
|
|
//HOSPITALS |
|
var hospitalslayer = circleMarker("red","Government Medical Infrastructure"); |
|
omnivore.csv(DATAPATH+'pune-medical.csv', null, hospitalslayer); |
|
layerControl.addOverlay(hospitalslayer , "Medical"); |
|
|
|
|
|
//ADMIN WARDS |
|
var adminlayer = defaultArea("magenta","Administrative Wards"); |
|
omnivore.geojson(DATAPATH+'pune-admin-wards.geojson', null, adminlayer); |
|
omnivore.csv(DATAPATH+'pune-admin-ward-offices.csv', null, adminlayer); |
|
layerControl.addOverlay(adminlayer , "Admin Wards"); |
|
|
|
//ASSEMBLY CONSTITUENCIES |
|
var assemblylayer = defaultArea("blue","Assembly Constituencies"); |
|
omnivore.geojson(DATAPATH+'pune-assembly-constituences.geojson', null, assemblylayer); |
|
layerControl.addOverlay(assemblylayer , "Assembly Constituencies"); |
|
|
|
//PMC ELECTION POLLING BOOTHS |
|
//CLUSTERING this layer.. we have to load it in the .on('ready') function. Else it doesn't load. |
|
var pmcpollingboothslayer = L.geoJson(null, { onEachFeature: defaultOnEachFeature }); |
|
omnivore.csv(DATAPATH+'pmc_polling_booths.csv', null, pmcpollingboothslayer) |
|
.on('error', function() { console.log("HEY! ERROR WHILE LOADING PMC POLLING BOOTHS!"); }) |
|
.on('ready', function(e) { |
|
var clustermarkers = new L.markerClusterGroup( { disableClusteringAtZoom: 16 } ); |
|
clustermarkers.addLayer(pmcpollingboothslayer); |
|
layerControl.addOverlay(clustermarkers , "PMC polling boths"); |
|
}); |
|
|
|
//######################################################################################### |
|
|
|
//######### FUNCTIONS ######### |
|
|
|
//#### DEFAULT EMPTY GEOJSON LAYERS FOR DEFINING CLICKING ETC |
|
function circleMarker(color, title, fields) { |
|
if(!color) color="orange"; |
|
return L.geoJson(null, { |
|
onEachFeature: function (feature, layer) { defaultOnEachFeature(feature, layer, title, fields); }, |
|
// style: {weight: 2, opacity: 1, color: 'black', dashArray: '4', fillOpacity: 0.2, fillColor: color }, |
|
pointToLayer: function (feature, latlng) { |
|
return L.circleMarker(latlng, { |
|
radius: 6, |
|
fillColor: color, |
|
color: "#000", |
|
weight: 1, |
|
opacity: 1, |
|
fillOpacity: 0.8 |
|
}); |
|
} |
|
}); |
|
} |
|
|
|
function defaultArea(color, title, fields) { |
|
if(!color) color="orange"; |
|
return L.geoJson(null, { |
|
onEachFeature: function (feature, layer) { defaultOnEachFeature(feature, layer, title, fields); }, |
|
style: {weight: 2, opacity: 1, color: 'black', dashArray: '4', fillOpacity: 0.2, |
|
fillColor: color } |
|
}); |
|
} |
|
|
|
function defaultOnEachFeature(feature, layer, title, fields) { |
|
var popupText = ""; |
|
var labelText = ""; |
|
var detailsText = "<h4>Pune Info"; |
|
if (title) detailsText += ': ' + title + '</h4>'; |
|
else detailsText += '</h4>'; |
|
if (feature.properties && feature.properties.name) { |
|
popupText += "<b>" + feature.properties.name.toString() + "</b>"; |
|
labelText = feature.properties.name.toString(); |
|
} |
|
/* |
|
if (feature.properties && feature.properties.description) { |
|
popupText += "<br>" + feature.properties.description.toString(); |
|
}*/ |
|
if (fields) { |
|
for (var prop in fields) { |
|
detailsText += "<b>" + fields[prop] + ":</b> " + feature.properties[fields[prop]] + "<br>"; |
|
} |
|
} else { |
|
for (var prop in feature.properties) { |
|
//if ( ( feature.properties[prop].toLowerCase().indexOf('.jpg') != -1 ) && ( feature.properties[prop].toLowerCase().indexOf('<img') == -1 ) ) |
|
//detailsText += '<img src="'+DATAPATH; |
|
//else |
|
detailsText += "<b>" + prop + ":</b> " + feature.properties[prop] + "<br>"; |
|
} |
|
} |
|
layer.bindPopup(popupText).bindLabel(labelText); |
|
layer.on({ |
|
click: function() { |
|
document.getElementById('sidepanel').innerHTML = detailsText; |
|
} |
|
}); |
|
|
|
} |
|
|
|
function areastyle(feature) { |
|
return { |
|
weight: 2, |
|
opacity: 1, |
|
color: 'black', |
|
dashArray: '4', |
|
fillOpacity: 0.2, |
|
fillColor: "orange" |
|
//fillColor: 'magenta' |
|
}; |
|
} |
|
|
|
function easynumber(N) { |
|
F = parseFloat(N); |
|
if(F == 0) return "No expenditure"; |
|
else if (!F) return N; |
|
else if(F >= 10000000 ) return "Rs." + F/10000000 + " crore"; |
|
else if(F >= 100000 ) return "Rs." + F/100000 + " lakh"; |
|
else if(F >= 1000 ) return "Rs." + F/1000 + " thousand"; |
|
else if(F >= 1) return "Rs." + F; |
|
} |
|
|
|
function commanumber(N) { |
|
F = parseInt(N); |
|
if( F >= 1000 ) return F; |
|
return F; |
|
} |
|
|
|
//for getting lat and long |
|
var popup = L.popup(); |
|
function onMapClick(e) { |
|
popup |
|
.setLatLng(e.latlng) |
|
.setContent("" + e.latlng.toString()) |
|
.openOn(map); |
|
} |
|
map.on('click', onMapClick); |
|
|
|
</script> |
|
</body> |
|
</html> |