Created
May 26, 2016 22:00
-
-
Save mappingvermont/1422f3b8ed56934fb2d02a9f93901e2b to your computer and use it in GitHub Desktop.
This file contains 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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset=utf-8 /> | |
<title>Filtering Pixels in Leaflet</title> | |
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' /> | |
<!-- Load Leaflet from CDN--> | |
<link rel="stylesheet" href="https://cdn.jsdelivr.net/leaflet/0.7.7/leaflet.css" /> | |
<script src="https://cdn.jsdelivr.net/leaflet/0.7.7/leaflet.js"></script> | |
<!-- slider library--> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/noUiSlider/8.2.1/nouislider.min.css" /> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/noUiSlider/8.2.1/nouislider.min.js"></script> | |
<style> | |
body { | |
margin:0; | |
padding:0; | |
} | |
#map { | |
position: absolute; | |
top:0; | |
bottom:0; | |
right:0;left:0; | |
} | |
#info-pane { | |
position: absolute; | |
top: 10px; | |
right: 10px; | |
min-width: 200px; | |
z-index: 10; | |
padding: 1em; | |
background: white; | |
} | |
.noUi-connect { | |
background: #CCC; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="map"></div> | |
<div id="info-pane" class="leaflet-bar"> | |
<div id="slider"></div> | |
<br> | |
<label id="min"> | |
0 meters | |
</label><br> | |
<label id="max"> | |
4000 meters | |
</label> | |
<hr> | |
<div id="pixel-value"></div> | |
</div> | |
<div id='photodiv'> | |
<img id="photo"/> | |
</div> | |
<script> | |
// create a UI slider for the end user to toggle the pixel range to display | |
var slider = document.getElementById('slider'); | |
noUiSlider.create(slider, { | |
start: [0, 4000], | |
step: 100, | |
connect: true, | |
range: { | |
'min': 0, | |
'max': 8000 | |
} | |
}); | |
// When the slider value changes, update the input and span | |
slider.noUiSlider.on('set', function (values, handle) { | |
document.getElementById('min').innerHTML = parseInt(values[0], 10) + ' meters'; | |
document.getElementById('max').innerHTML = parseInt(values[1], 10) + ' meters'; | |
// redraw the tiles without resetting | |
for (t in lerc._tiles) | |
lerc._redrawTile(lerc._tiles[t]); | |
}); | |
var southWest = L.latLng(-90, -179), | |
northEast = L.latLng(90, 179), | |
worldBounds = L.latLngBounds(southWest, northEast); | |
var map = L.map('map', { | |
noWrap: true, | |
minZoom: 3, | |
maxBounds: worldBounds | |
}).setView([43.684639, -79.384956], 15); | |
var toronto = L.tileLayer.canvas({ | |
noWrap: true, | |
attribution: 'USGS, Esri' | |
}); | |
toronto.drawTile = function (canvas, tilePoint, zoom) { | |
drawData = function (img, ctx) { | |
ctx.drawImage(img, 0, 0); | |
//console.log(img); | |
var width = img.width; | |
var height = img.height; | |
var min = slider.noUiSlider.get()[0]; | |
var max = slider.noUiSlider.get()[1]; | |
var imageData = ctx.getImageData(0, 0, width, height); | |
var data = imageData.data; | |
// Invert image | |
data = invert(data) | |
ctx.putImageData(imageData, 0, 0); | |
} | |
var tileIndex = tilePoint.x + ':' + tilePoint.y; | |
var tile = this._tiles[tileIndex]; | |
var xhr = new XMLHttpRequest(); | |
xhr.responseType = "arraybuffer"; | |
var url = 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/' + zoom + '/' + tilePoint.y + '/' + tilePoint.x; | |
xhr.open("Get", url, true); | |
xhr.send(); | |
xhr.onreadystatechange = function () { | |
if (this.readyState == 4 && this.status == 200) { | |
var arrayBufferView = new Uint8Array( xhr.response ); | |
var blob = new Blob( [ arrayBufferView ], { type: "image/jpeg" } ); | |
var imageUrl = URL.createObjectURL( blob ); | |
var img = new Image(); | |
img.onload = function() { | |
tile.img = img | |
drawData(tile.img, canvas.getContext('2d')); | |
} | |
img.src = imageUrl | |
} | |
} | |
}; | |
map.on('mousemove', function (e) { | |
// the x/y of the tile url | |
var layerPoint = map.project(e.latlng).floor(); | |
var tilePoint = layerPoint.divideBy(256).floor(); | |
var block = toronto._tiles[tilePoint.x + ':' + tilePoint.y].img; | |
var layerPoint_px = e.layerPoint | |
// Read the data value from the block if it exists | |
if (block) { | |
// No idea how this black magic works, but it does | |
var pointInTile = layerPoint.subtract(tilePoint.multiplyBy(256)); | |
// read in the image | |
var canvas = document.createElement('canvas'); | |
canvas.width = block.width; | |
canvas.height = block.height; | |
canvas.getContext('2d').drawImage(block, 0, 0, block.width, block.height); | |
// Get the rgba color, using the inversion | |
var rgba = invert(canvas.getContext('2d').getImageData(pointInTile.x, pointInTile.y, 1, 1).data); | |
var rgba_txt = 'rgba(' + rgba[0] + ',' + rgba[1] + ',' + rgba[2] + ',' + rgba[3] + ')'; | |
// Color the info pane to match | |
var info = document.getElementById('info-pane'); | |
info.style.background = rgba_txt; | |
} else { | |
document.getElementById('pixel-value').innerHTML = "Elevation: undefined"; | |
} | |
}) | |
var invert = function(data) { | |
for (var i = 0; i < data.length; i += 4) { | |
data[i] = 255 - data[i]; // red | |
data[i + 1] = 255 - data[i + 1]; // green | |
data[i + 2] = 255 - data[i + 2]; // blue | |
} | |
return data | |
}; | |
var decode_date = function(rgba) { | |
var julian_day = rgba[0] + rgba[1] | |
var band3_str = rgba[2].toString(); | |
var confidence = parseInt(band3_str[0]) | |
var year = parseInt(band3_str.slice(1)) + 2000 | |
//http://stackoverflow.com/questions/4048688 | |
var date = new Date(year, 0); | |
var final_date = new Date(date.setDate(julian_day)); | |
return [date, confidence] | |
}; | |
toronto.addTo(map); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment