Created
February 21, 2024 12:56
-
-
Save davidoesch/433a059a5160e805f5685f974fce6a8b to your computer and use it in GitHub Desktop.
leaflet_vectortiles_removelayer
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" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> | |
<title>Vector Map Demo (Leaflet)</title> | |
<style> | |
#map { | |
bottom: 0; | |
left: 0; | |
position: absolute; | |
right: 0; | |
top: 0; | |
} | |
</style> | |
<!-- Leaflet --> | |
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" /> | |
<script type="text/javascript" src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script> | |
<!-- MapLibre GL JS (still required to handle the rendering) --> | |
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.2/dist/leaflet.css" /> | |
<script src="https://unpkg.com/leaflet@1.9.2/dist/leaflet.js"></script> | |
<!-- Add maplibre-gl-js --> | |
<link href='https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.css' rel='stylesheet' /> | |
<script src='https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.js'></script> | |
<!-- Add maplibre-gl-leaflet --> | |
<script src="https://unpkg.com/@maplibre/maplibre-gl-leaflet@0.0.17/leaflet-maplibre-gl.js"></script>> | |
<script src="https://unpkg.com/proj4"></script> | |
<script src="https://unpkg.com/georaster"></script> | |
<script src="https://unpkg.com/georaster-layer-for-leaflet"></script> | |
</head> | |
<body> | |
<div id="map"></div> | |
<script type="text/javascript"> | |
// Initialize a map centered at (53, 12) at zoom level 5 | |
var map = L.map('map').setView([53, 12], 5); | |
L.maplibreGL({ | |
style: 'https://vectortiles.geo.admin.ch/styles/ch.swisstopo.leichte-basiskarte-imagery.vt/style.json', // Style URL; see our documentation for more options | |
}).addTo(map); | |
// Wait for the style to load | |
map.on('styledata', function() { | |
// Check if the layer exists | |
if (map.hasLayer('swissimage')) { | |
// Remove the layer | |
map.removeLayer('swissimage'); | |
} | |
}); | |
const url_to_geotiff_file = new URLSearchParams(location.search).get("url"); | |
console.log("url_to_geotiff_file:", url_to_geotiff_file); | |
if (!url_to_geotiff_file) { | |
setTimeout(function() { | |
// If no URL is provided, redirect to a sample GeoTIFF | |
const parser = new URL(window.location); | |
parser.searchParams.set("url", "https://d29cp2gnktw6by.cloudfront.net/data/S2_LEVEL_2A/20240101T102431/S2_L2A_SR_20240101T102431_20240101T102428_10M_run20240102.tif"); | |
window.location = parser.href; | |
}, 2 * 1000); | |
} else { | |
console.log("url_to_geotiff_file:", url_to_geotiff_file); | |
// Parse the GeoTIFF data | |
parseGeoraster(url_to_geotiff_file).then(function (georaster) { | |
console.log("georaster:", georaster); | |
// based on https://custom-scripts.sentinel-hub.com/custom-scripts/sentinel-2/l2a_optimized/ | |
// Contrast enhance / highlight compress | |
const maxR = 3.0; // max reflectance | |
const midR = 0.13; | |
const sat = 1.2; | |
const gamma = 1.8; | |
function evaluatePixel(val0,val1,val2) { | |
//console.log("val0:", val0, "val1:", val1, "val2:", val2); | |
const rgbLin = satEnh(sAdj(val0), sAdj(val1), sAdj(val2)); | |
//console.log("rgbLin:", rgbLin); | |
//console.log("sRGB0:", sRGB(rgbLin[0]), "sRGB1:", sRGB(rgbLin[1]), "sRGB2:", sRGB(rgbLin[2])); | |
return [sRGB(rgbLin[0]), sRGB(rgbLin[1]), sRGB(rgbLin[2])]; | |
} | |
function sAdj(a) { | |
return adjGamma(adj(a, midR, 1, maxR)); | |
} | |
const gOff = 0.01; | |
const gOffPow = Math.pow(gOff, gamma); | |
const gOffRange = Math.pow(1 + gOff, gamma) - gOffPow; | |
function adjGamma(b) { | |
return (Math.pow((b + gOff), gamma) - gOffPow) / gOffRange; | |
} | |
// Saturation enhancement | |
function satEnh(r, g, b) { | |
const avgS = (r + g + b) / 3.0 * (1 - sat); | |
return [clip(avgS + r * sat), clip(avgS + g * sat), clip(avgS + b * sat)]; | |
} | |
function clip(s) { | |
return s < 0 ? 0 : s > 1 ? 1 : s; | |
} | |
//contrast enhancement with highlight compression | |
function adj(a, tx, ty, maxC) { | |
var ar = clip(a / maxC, 0, 1); | |
return ar * (ar * (tx / maxC + ty - 1) - ty) / (ar * (2 * tx / maxC - 1) - tx / maxC); | |
} | |
const sRGB = (c) => c <= 0.0031308 ? (12.92 * c) : (1.055 * Math.pow(c, 0.41666666666) - 0.055); | |
const layer = new GeoRasterLayer({ | |
attribution: "swisstopo, contains modified Copernicus Sentinel data 2024", | |
debugLevel: 0, | |
georaster, | |
resolution: 128, | |
opacity:1, | |
resampleMethod: "nearest", | |
pixelValuesToColorFn: values => { | |
// Check if any of the bands have a value of 9999 | |
if (values.some(value => value === 9999 )) { | |
//if (values.some(value => value === 9999 || value === 0)) { | |
// If any band has a value of 9999 , return transparent color | |
return 'rgba(0, 0, 0, 0)'; // Transparent color | |
} else { | |
// Apply min-max normalization to each band | |
const r = Math.round(evaluatePixel(values[0]/10000, values[1]/10000, values[2]/10000)[0] * 255); | |
const g = Math.round(evaluatePixel(values[0]/10000, values[1]/10000, values[2]/10000)[1] * 255); | |
const b = Math.round(evaluatePixel(values[0]/10000, values[1]/10000, values[2]/10000)[2] * 255); | |
// Return RGB color | |
return `rgba(${r},${g},${b},1)`; | |
} | |
} | |
}); | |
layer.addTo(map); | |
map.fitBounds(layer.getBounds()); | |
}); | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment