import { asArray as ol_color_asArray } from 'ol/color.js' /** Helper for loading BIL-32 (Band Interleaved by Line) image * @param {string} src * @param {function} onload a function that takes a Float32Array and a ol.size.Size (array size) * @param {function} onerror * @private */ var ol_ext_imageLoader_loadBILImage = function(src, onload, onerror) { var size = [ parseInt(src.replace(/.*WIDTH=(\d*).*/i,'$1')), parseInt(src.replace(/.*HEIGHT=(\d*).*/i,'$1')) ]; var xhr = new XMLHttpRequest(); xhr.responseType = 'blob'; xhr.addEventListener('loadend', function () { var resp = this.response; if (resp !== undefined) { const reader = new FileReader(); // Get as array reader.addEventListener('loadend', (e) => { var data = new Float32Array(e.target.result); onload(data, size); }); // Start reading the blob reader.readAsArrayBuffer(resp); // tile.getImage().src = URL.createObjectURL(blob); } else { onerror(); } }); xhr.addEventListener('error', function () { onerror(); }); xhr.open('GET', src); xhr.send(); }; /** Helper for loading image * @param {string} src * @param {function} onload a function that takes a an image and a ol.size.Size * @param {function} onerror * @private */ var ol_ext_imageLoader_loadImage = function(src, onload, onerror) { var xhr = new XMLHttpRequest(); xhr.responseType = 'blob'; xhr.addEventListener('loadend', function () { var resp = this.response; if (resp !== undefined) { var img = new Image(); img.onload = function() { onload(img, [img.naturalWidth, img.naturalHeight]); } img.src = URL.createObjectURL(resp); } else { onerror(); } }); xhr.addEventListener('error', function () { onerror(); }); xhr.open('GET', src); xhr.send(); }; /** Get a TileLoadFunction to transform tiles images * @param {function} setPixel a function that takes a Uint8ClampedArray and the pixel position to transform * @returns {function} an ol/Tile~LoadFunction */ var ol_ext_imageLoader_pixelTransform = function(setPixel) { return function(tile, src) { ol_ext_imageLoader_loadImage( src, function(img, size) { var canvas = document.createElement('canvas'); canvas.width = size[0]; canvas.height = size[1]; var ctx = canvas.getContext('2d'); ctx.drawImage(img, 0, 0); var imgData = ctx.getImageData(0, 0, size[0], size[1]); var pixels = imgData.data; for (var i = 0; i < pixels.length; i += 4) { setPixel(pixels, i, size); } ctx.putImageData(imgData, 0, 0); tile.setImage(canvas); }, function() { tile.setState(3); } ); } }; /** Get a TileLoadFunction to transform tiles into grayscale images * @returns {function} an ol/Tile~LoadFunction */ var ol_ext_imageLoader_grayscale = function() { return ol_ext_imageLoader_pixelTransform(function(pixels, i) { pixels[i] = pixels[i + 1] = pixels[i + 2] = parseInt(3*pixels[i] + 4*pixels[i + 1] + pixels[i + 2] >>> 3); }) }; /** Get a TileLoadFunction to turn color or a color range transparent * @param {ol.color.Color|Array} colors color or color range to turn transparent * @returns {function} an ol/Tile~LoadFunction */ var ol_ext_imageLoader_transparent = function(colors) { var color1, color2; if (colors instanceof Array) { color1 = colors[0]; color2 = colors[1]; } var color = color1 = ol_color_asArray(color1); if (!color2) { return ol_ext_imageLoader_pixelTransform(function(pixels, i) { if (pixels[i]===color[0] && pixels[i+1]===color[1] && pixels[i+2]===color[2]) { pixels[i+3] = 0; } }) } else { color2 = ol_color_asArray(color2); color = [Math.min(color1[0], color2[0]), Math.min(color1[1], color2[1]), Math.min(color1[2], color2[2])]; color2 = [Math.max(color1[0], color2[0]), Math.max(color1[1], color2[1]), Math.max(color1[2], color2[2])]; return ol_ext_imageLoader_pixelTransform(function(pixels, i) { if (pixels[i]>=color1[0] && pixels[i]<=color2[0] && pixels[i+1]>=color[1] && pixels[i+1]<=color2[1] && pixels[i+2]>=color[2] && pixels[i+2]<=color2[2]) { pixels[i+3] = 0; } }) } }; /** Returns an Imageloader function to load an x-bil-32 image as sea level map * to use as a ol/Tile~LoadFunction or ol/Image~LoadFunction * @param { number } level * @param {*} options * @param { ol.Color } [options.color] fill color * @param { boolean } [options.opacity=true] smooth color on border * @param { number } [options.minValue=-Infinity] minimum level value * @returns {function} an ol/Tile~LoadFunction */ var ol_ext_imageLoader_seaLevelMap = function(level, options) { options = options || {}; var h0 = Math.max(level + .01, .01); var c = options.color ? ol_color_asArray(options.color) : [135,203,249]; var min = typeof(options.minValue) === 'number' ? options.minValue : -Infinity; var opacity = options.opacity!==false; return ol_ext_imageLoader_elevationMap(function(h) { if (h < h0 && h > min) { return [c[0], c[1], c[2], opacity ? 255 * (h0-h) / h0 : 255]; } else { return [0,0,0,0]; } }) }; /** Shaded relief ? not/bad working yet... * @returns {function} an ol/Tile~LoadFunction * @private */ var ol_ext_imageLoader_shadedRelief = function() { var sunElev = Math.PI / 4; var sunAzimuth = 2*Math.PI - Math.PI / 4; return function (tile, src) { ol_ext_imageLoader_loadBILImage( src, function(data, size) { var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); var width = canvas.width = size[0]; var height = canvas.height = size[1]; var imgData = ctx.getImageData(0, 0, width, height); var pixels = imgData.data; function getIndexForCoordinates(x, y) { return x + y*width; } for (var x=0; x 0 ) { if ( sly > 0 ) azimuth = phi + 1.5*Math.PI; else if ( sly < 0 ) azimuth = 1.5*Math.PI - phi; else phi = 1.5*Math.PI; } else if ( slx < 0 ){ if ( sly < 0 ) azimuth = phi + .5*Math.PI; else if ( sly > 0 ) azimuth = .5*Math.PI - phi; else azimuth = .5*Math.PI; } else { if ( sly < 0 ) azimuth = Math.PI; else if ( sly > 0 ) azimuth = 0; } // get luminance var lum = Math.cos( azimuth - sunAzimuth )*Math.cos( Math.PI*.5 - Math.atan(sl0) )*Math.cos( sunElev ) + Math.sin( Math.PI*.5 - Math.atan(sl0) )*Math.sin( sunElev ); if (lum<0) lum = 0; lum = Math.sqrt(lum*.8 + .5); var p = getIndexForCoordinates(x,y) * 4; pixels[p] = pixels[p+1] = pixels[p+2] = 0; pixels[p+3] = 255 - lum*255; } ctx.putImageData(imgData, 0, 0); tile.setImage(canvas); }, function () { tile.setState(3); } ) }; }; /** Get a TileLoadFunction to load an x-bil-32 image as elevation map (ie. pixels colors codes elevations as terrain-RGB) * If getPixelColor is not define pixel store elevation as rgb, use {@link ol_ext_getElevationFromPixel} to get elevation from pixel * @param {function} [getPixelColor] a function that taket an elevation and return a color array [r,g,b,a], default store elevation as terrain-RGB * @returns {function} an ol/Tile~LoadFunction */ var ol_ext_imageLoader_elevationMap = function(getPixelColor) { if (typeof(getPixelColor) !== 'function') getPixelColor = ol_ext_getPixelFromElevation; return function (tile, src) { ol_ext_imageLoader_loadBILImage( src, function(data, size) { var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); canvas.width = size[0]; canvas.height = size[1]; var imgData = ctx.getImageData(0, 0, size[0], size[1]); var pixels = imgData.data; for (var i=0; i -12000 m * - 2 digits (0.01 m) * @param {number} height elevation * @returns {Array} pixel value */ var ol_ext_getPixelFromElevation = function(height) { var h = Math.round(height*100 + 1200000); var pixel = [ h >> 16, (h % 65536) >> 8, h % 256, 255 ]; return pixel; }; /** Convert pixel (terrain-RGB) to elevation * @see ol_ext_getPixelFromElevation * @param {Array} pixel the pixel value * @returns {number} elevation */ var ol_ext_getElevationFromPixel = function(pixel) { // return -10000 + (pixel[0] * 65536 + pixel[1] * 256 + pixel[2]) * 0.01; return -12000 + ((pixel[0] << 16) + (pixel[1] << 8) + pixel[2]) * 0.01; }; export { ol_ext_imageLoader_loadBILImage as loadBILImage } export { ol_ext_imageLoader_seaLevelMap as seaLevelMap, ol_ext_imageLoader_elevationMap as elevationMap } export { ol_ext_getPixelFromElevation as getPixelFromElevation, ol_ext_getElevationFromPixel as getElevationFromPixel } export { ol_ext_imageLoader_grayscale as grayscale, ol_ext_imageLoader_transparent as transparent } export { ol_ext_imageLoader_pixelTransform as pixelTransform } export { ol_ext_imageLoader_shadedRelief }