Forked from mapsense-examples/L.TileLayer.d3_JSON_mapsense.js
Last active
August 29, 2015 14:22
-
-
Save mukhtyar/28a51aa05c462f5ddc82 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- Based on following blocks: | |
mapsense-examples’s block | |
http://bl.ocks.org/mapsense-examples/be0ad69cbea40d842726 | |
zanarmstrong’s block | |
http://bl.ocks.org/zanarmstrong/ddff7cd0b1220bc68a58 | |
--> | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content='initial-scale=1,maximum-scale=1,user-scalable=no' /> | |
<link rel="stylesheet" href="http://leafletjs.com/dist/leaflet.css" media="screen" type="text/css"> | |
<link rel="stylesheet" href="https://developer.mapsense.co/mapsense.css" media="screen" type="text/css"> | |
<link rel="stylesheet" href="slider.css"> | |
<script src='http://d3js.org/d3.v3.min.js' type="text/javascript"></script> | |
<script src='http://d3js.org/topojson.v1.min.js' type="text/javascript"></script> | |
<script src='http://leafletjs.com/dist/leaflet.js' type="text/javascript"></script> | |
<script src='L.TileLayer.d3_JSON_mapsense.js' type="text/javascript"></script> | |
<style> | |
html, body { | |
width: 100%; height: 100%; margin: 0; padding: 0; | |
} | |
#myMap { | |
width: 100%; height: 800px; margin-top: 50px; padding: 0; | |
} | |
#options { | |
width: 100%; height: 10%; | |
} | |
.leaflet-container { | |
background: transparent; | |
outline: 0; | |
} | |
.mapsense-light.tile-background { | |
fill: none; | |
} | |
.mapsense-light.roads { | |
stroke: #945454; | |
} | |
.tile-slider { | |
padding: 6px 8px; | |
font: 14px/16px 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; | |
} | |
.tile-slider h4 { | |
margin: 0 0 5px; | |
color: #777; | |
} | |
.tile-slider { | |
margin-bottom: 50px; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="options"> | |
<h1 style="color:white;margin-left:20px;font-size:3em;">Cal-Adapt CMIP5 LOCA CCSM4 Maximum Temperature</h1> | |
<select id = "month" style="margin-left:20px;font-size:1em;"> | |
<option value="01">January</option> | |
<option value="02">February</option> | |
<option value="03">March</option> | |
<option value="04">April</option> | |
<option value="05">May</option> | |
<option value="06">June</option> | |
<option value="07" selected="selected">July</option> | |
<option value="08">August</option> | |
<option value="09">September</option> | |
<option value="10">October</option> | |
<option value="11">November</option> | |
<option value="12">December</option> | |
</select> | |
<select id = "year" style="margin-left:20px;font-size:1em;"> | |
<option value="1950">1950</option> | |
<option value="1960">1960</option> | |
<option value="1970" selected="selected">1970</option> | |
<option value="1980">1980</option> | |
<option value="1990">1990</option> | |
<option value="2000">2000</option> | |
<option value="2002">2002</option> | |
<option value="2005">2005</option> | |
</select> | |
</div> | |
<div id="myMap"></div> | |
<script> | |
var map = L.map('myMap').setView([38.8, -121.5], 7); | |
var my_key = "key-b92646a22593424f8c3a42c1b9e540ff"; | |
new L.tileLayer("http://{s}.mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.jpg", { | |
attribution: '<a href="http://developer.mapquest.com/web/products/open/map</a>Mapquest</a>', | |
subdomains: ["otile1", "otile2", "otile3", "otile4"], | |
opacity: 0.5 | |
}).addTo(map); | |
var year = d3.select('#year').property('value'); | |
var month = d3.select('#month').property('value'); | |
console.log(year, month); | |
var tasmaxUrl = "https://dev-ecoengine.berkeley.edu/api/tiles/tasmax-" + year + "-" + month + "/{z}/{x}/{y}/" | |
var tasmax = new L.tileLayer(tasmaxUrl, { | |
attribution: '<a href="http://ecoengine.berkeley.edu</a>Cal-Adapt</a>' | |
}).addTo(map); | |
// Hat Tip! http://bl.ocks.org/NelsonMinar/5624141 | |
// Add a fake GeoJSON line to coerce Leaflet into creating the <svg> tag that d3_geoJson needs | |
new L.geoJson({"type": "LineString","coordinates":[[0,0],[0,0]]}).addTo(map); | |
var mapsense_url = "https://{s}-api.mapsense.co/explore/api/universes/mapsense.earth/{z}/{x}/{y}.topojson?s=10&ringSpan=8&api-key=" + my_key; | |
mapsense_url += "&where=layer=='roads'"; | |
new L.TileLayer.d3_JSON(mapsense_url, { | |
attribution: '<a target="_blank" href="https://developer.mapsense.co/tileViewer/?tileset=mapsense.earth">©Mapsense ©OpenStreetMap</a>', | |
// https://developer.mapsense.co/documentation/basemap | |
//mapsenseStyle: "vintage" // choose a basemap style, or style your own at styler.mapsense.co | |
}).addTo(map); | |
function updateTiles(month, year) { | |
console.log(month, year); | |
var url = "https://dev-ecoengine.berkeley.edu/api/tiles/tasmax-" + year + "-" + month + "/{z}/{x}/{y}/" | |
tasmax.setUrl(url); | |
} | |
// handle on click event | |
d3.select('#month') | |
.on('change', function() { | |
var currentMonth = d3.select(this).property('value'); | |
updateTiles(currentMonth, year); | |
}); | |
// handle on click event | |
d3.select('#year') | |
.on('change', function() { | |
var currentYear = d3.select(this).property('value'); | |
updateTiles(month, currentYear); | |
}); | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- Based on following blocks: | |
mapsense-examples’s block | |
http://bl.ocks.org/mapsense-examples/be0ad69cbea40d842726 | |
zanarmstrong’s block | |
http://bl.ocks.org/zanarmstrong/ddff7cd0b1220bc68a58 | |
--> | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content='initial-scale=1,maximum-scale=1,user-scalable=no' /> | |
<link rel="stylesheet" href="http://leafletjs.com/dist/leaflet.css" media="screen" type="text/css"> | |
<link rel="stylesheet" href="https://developer.mapsense.co/mapsense.css" media="screen" type="text/css"> | |
<link rel="stylesheet" href="slider.css"> | |
<script src='http://d3js.org/d3.v3.min.js' type="text/javascript"></script> | |
<script src='http://d3js.org/topojson.v1.min.js' type="text/javascript"></script> | |
<script src='http://leafletjs.com/dist/leaflet.js' type="text/javascript"></script> | |
<script src='L.TileLayer.d3_JSON_mapsense.js' type="text/javascript"></script> | |
<style> | |
html, body, #myMap { width: 100%; height: 100%; margin: 0; padding: 0;} | |
.leaflet-container { | |
background: transparent; | |
outline: 0; | |
} | |
.mapsense-light.tile-background { | |
fill: none; | |
} | |
.mapsense-light.roads { | |
stroke: #945454; | |
} | |
.tile-slider { | |
padding: 6px 8px; | |
font: 14px/16px 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; | |
} | |
.tile-slider h4 { | |
margin: 0 0 5px; | |
color: #777; | |
} | |
.tile-slider { | |
margin-bottom: 50px; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="myMap"></div> | |
<script> | |
var map = L.map('myMap').setView([38.8, -121.5], 7); | |
var my_key = "key-b92646a22593424f8c3a42c1b9e540ff"; | |
new L.tileLayer("http://{s}.mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.jpg", { | |
attribution: '<a href="http://developer.mapquest.com/web/products/open/map</a>Mapquest</a>', | |
subdomains: ["otile1", "otile2", "otile3", "otile4"], | |
opacity: 0.5 | |
}).addTo(map); | |
var tasmax = new L.tileLayer("https://dev-ecoengine.berkeley.edu/api/tiles/tasmax-1954-07/{z}/{x}/{y}/", { | |
attribution: '<a href="http://ecoengine.berkeley.edu</a>Cal-Adapt</a>' | |
}).addTo(map); | |
// Hat Tip! http://bl.ocks.org/NelsonMinar/5624141 | |
// Add a fake GeoJSON line to coerce Leaflet into creating the <svg> tag that d3_geoJson needs | |
new L.geoJson({"type": "LineString","coordinates":[[0,0],[0,0]]}).addTo(map); | |
var mapsense_url = "https://{s}-api.mapsense.co/explore/api/universes/mapsense.earth/{z}/{x}/{y}.topojson?s=10&ringSpan=8&api-key=" + my_key; | |
mapsense_url += "&where=layer=='roads'"; | |
new L.TileLayer.d3_JSON(mapsense_url, { | |
attribution: '<a target="_blank" href="https://developer.mapsense.co/tileViewer/?tileset=mapsense.earth">©Mapsense ©OpenStreetMap</a>', | |
// https://developer.mapsense.co/documentation/basemap | |
//mapsenseStyle: "vintage" // choose a basemap style, or style your own at styler.mapsense.co | |
}).addTo(map); | |
var info = L.control({position: 'bottomleft'}); | |
info.onAdd = function (map) { | |
this._div = L.DomUtil.create('div', 'tile-slider'); // create a div with a class "tile-slider" | |
this.update(); | |
return this._div; | |
}; | |
// method that we will use to update the control based on feature properties passed | |
info.update = function (props) { | |
this._div.innerHTML = '<h4>Year Slider</h4>'; | |
}; | |
info.addTo(map); | |
//year slider code | |
formatDate = d3.time.format("%Y"); | |
// parameters | |
var margin = { | |
top: 50, | |
right: 50, | |
bottom: 50, | |
left: 50 | |
}, | |
width = 500 - margin.left - margin.right, | |
height = 100 - margin.bottom - margin.top; | |
// scale function | |
var timeScale = d3.time.scale() | |
.domain([new Date('1951'), new Date('2006')]) | |
.range([0, width]) | |
.clamp(true); | |
// initial value | |
var startValue = timeScale(new Date('1955')); | |
startingValue = new Date('1955'); | |
////////// | |
// defines brush | |
var brush = d3.svg.brush() | |
.x(timeScale) | |
.extent([startingValue, startingValue]) | |
.on("brush", brushed); | |
var svg = d3.select(".tile-slider").append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.append("g") | |
// classic transform to position g | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
svg.append("g") | |
.attr("class", "x axis") | |
// put in middle of screen | |
.attr("transform", "translate(0," + height / 2 + ")") | |
// inroduce axis | |
.call(d3.svg.axis() | |
.scale(timeScale) | |
.orient("bottom") | |
.tickFormat(function(d) { | |
return formatDate(d); | |
}) | |
.tickSize(0) | |
.tickPadding(12) | |
.tickValues([timeScale.domain()[0], timeScale.domain()[1]])) | |
.select(".domain") | |
.select(function() { | |
console.log(this); | |
return this.parentNode.appendChild(this.cloneNode(true)); | |
}) | |
.attr("class", "halo"); | |
var slider = svg.append("g") | |
.attr("class", "slider") | |
.call(brush); | |
slider.selectAll(".extent,.resize") | |
.remove(); | |
slider.select(".background") | |
.attr("height", height); | |
var handle = slider.append("g") | |
.attr("class", "handle") | |
handle.append("path") | |
.attr("transform", "translate(0," + height / 2 + ")") | |
.attr("d", "M 0 -20 V 20") | |
handle.append('text') | |
.text(startingValue) | |
.attr("transform", "translate(" + (-18) + " ," + (height / 2 - 25) + ")"); | |
slider | |
.call(brush.event) | |
function brushed() { | |
var value = brush.extent()[0]; | |
var year = formatDate(value); | |
if (d3.event.sourceEvent) { // not a programmatic event | |
value = timeScale.invert(d3.mouse(this)[0]); | |
brush.extent([value, value]); | |
} | |
handle.attr("transform", "translate(" + timeScale(value) + ",0)"); | |
handle.select('text').text(formatDate(value)); | |
var tasmaxUrl = "https://dev-ecoengine.berkeley.edu/api/tiles/tasmax-" + year + "-07/{z}/{x}/{y}/" | |
tasmax.setUrl(tasmaxUrl); | |
} | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
L.TileLayer.d3_JSON = L.TileLayer.extend({ | |
//extending L.TileLayer to support topoJSON and geoJSON vector sources | |
//rendering with d3, borrows from zjonsson & https://github.com/glenrobertson/leaflet-tilelayer-geojson/ | |
onAdd: function(map) { | |
var map_container_svg = d3.select(map._container).select("svg"); | |
L.TileLayer.prototype.onAdd.call(this, map); | |
this.mapsenseStyle = this.options.mapsenseStyle || 'light'; | |
this._path = d3.geo.path().projection({ | |
stream: function(stream) { | |
// no sampling along great arc | |
// just a pure projection, without the default d3 projection-stream pipeline | |
// so, long lines don't make curves, i.e. they obey the mercator projection | |
return { | |
point: function(x, y) { | |
var p = map.latLngToLayerPoint(new L.LatLng(y, x)); | |
stream.point(p.x, p.y); | |
}, | |
lineStart: stream.lineStart, | |
lineEnd: stream.lineEnd, | |
polygonStart: stream.polygonStart, | |
polygonEnd: stream.polygonEnd, | |
sphere: stream.sphere | |
}; | |
} | |
}); | |
this.on("tileunload", function(d) { | |
if (d.tile.xhr) d.tile.xhr.abort(); | |
if (d.tile.nodes) d.tile.nodes.remove(); | |
d.tile.nodes = null; | |
d.tile.xhr = null; | |
}); | |
}, | |
_loadTile: function(tile, tilePoint) { | |
var self = this; | |
this._adjustTilePoint(tilePoint); | |
var mapsenseStyle = this.mapsenseStyle; | |
if (!tile.nodes && !tile.xhr) { | |
tile.xhr = d3.json(this.getTileUrl(tilePoint), function(data) { | |
var geoJson; | |
if (data === '') { | |
// Ignore empty submissions | |
} else { | |
geoJson = topo2Geo(data); | |
} | |
tile.xhr = null; | |
nwPoint = tilePoint.multiplyBy(256); | |
sePoint = nwPoint.add([256, 256]); | |
nw = map.unproject(nwPoint); | |
se = map.unproject(sePoint); | |
var point = map.latLngToLayerPoint(new L.LatLng(nw.lat, nw.lng)); | |
var tile_coords = "tile_" + point.x + "_" + point.y; | |
d3.select(map._container).select("svg") | |
.append("clipPath") | |
.attr("id", tile_coords) | |
.attr("style", "fill: none; stroke: pink; transform: translate(" + point.x + "px, " + point.y + "px); -webkit-transform: translate(" + point.x + "px, " + point.y + "px);") | |
.append("rect") | |
.attr("width", "256") | |
.attr("height", "256"); | |
d3.select(map._container).select("svg") | |
.append("rect") | |
.attr("style", "transform: translate(" + point.x + "px, " + point.y + "px); -webkit-transform: translate(" + point.x + "px, " + point.y + "px);") | |
.attr("width", "256") | |
.attr("height", "256") | |
.attr("class", "mapsense-"+self.mapsenseStyle +" tile-background"); | |
tile.nodes = d3.select(map._container).select("svg").append("g"); | |
// tile.nodes is now a bunch of appended g's | |
var grp = tile.nodes.selectAll("path") | |
.data(geoJson.features) | |
.enter() | |
.append("g") | |
.attr("class", "groupr"); | |
grp.append("path") | |
.attr("d", self._path) | |
.attr("clip-path", "url(#" + tile_coords + ")") | |
.attr("class", self.options.class) | |
.attr("class", function(d) { // this data is a bunch of features | |
var zoomClass = "_" + Math.floor(map.getZoom()); | |
var classes = ['mapsense-'+self.mapsenseStyle]; | |
if (d.properties) { | |
if (d.properties) { | |
if (d.properties.layer) | |
classes.push(d.properties.layer); | |
if (d.properties.natural) | |
classes.push(d.properties.natural); | |
if (d.properties.sub_layer) | |
classes.push(d.properties.sub_layer); | |
} else { | |
classes.push('unknown'); | |
} | |
classes = classes.join(' '); | |
return classes; | |
} else {} | |
}); | |
}); | |
} | |
} | |
}); | |
function topologyFeatures(topology) { | |
function convert(topology, object, layer, features) { | |
var featureOrCollection = topojson.feature(topology, object), | |
layerFeatures; | |
if (featureOrCollection.type === "FeatureCollection") { | |
layerFeatures = featureOrCollection.features; | |
} else { | |
layerFeatures = [featureOrCollection]; | |
} | |
layerFeatures.forEach(function(f) { | |
f.properties.layer = layer; | |
}); | |
features.push.apply(features, layerFeatures); | |
} | |
var features = []; | |
for (var o in topology.objects) { | |
convert(topology, topology.objects[o], o, features); | |
} | |
return features; | |
} | |
function topo2Geo(tj) { | |
var gj = { | |
type: "FeatureCollection", | |
features: topologyFeatures(tj) | |
}; | |
return gj; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
background-color: #393939; | |
font-size: 14px; | |
font-family: 'Raleway', sans-serif; | |
} | |
p { | |
color: white; | |
margin: 50px; | |
} | |
a { | |
color: #4FDEF2; | |
} | |
.axis { | |
fill: gray; | |
-webkit-user-select: none; | |
-moz-user-select: none; | |
user-select: none; | |
} | |
.axis .halo { | |
stroke: gray; | |
stroke-width: 4px; | |
stroke-linecap: round; | |
} | |
.slider .handle path { | |
stroke: white; | |
stroke-width: 3px; | |
stroke-linecap: round; | |
pointer-events: none; | |
} | |
.slider .handle text { | |
fill: white; | |
text-align: center; | |
font-size: 18px; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment