add geotiffJS library full git

This commit is contained in:
JS 2023-10-29 22:27:19 +01:00
parent 2e27417fc5
commit aef672986a
62 changed files with 21999 additions and 0 deletions

View file

@ -0,0 +1 @@
data

View file

@ -0,0 +1,3 @@
FROM nginx
COPY nginx.conf /etc/nginx/conf.d/default.conf

View file

@ -0,0 +1,4 @@
*zip*
*tif*
*html
*xml

View file

@ -0,0 +1,91 @@
set -e
wget https://github.com/EOxServer/autotest/raw/f8d9f4bde6686abbda09c711d4bf5239f5378aa9/autotest/data/meris/MER_FRS_1P_reduced/ENVISAT-MER_FRS_1PNPDE20060816_090929_000001972050_00222_23322_0058_uint16_reduced_compressed.tif -O initial.tiff
wget https://github.com/EOxServer/autotest/raw/f8d9f4bde6686abbda09c711d4bf5239f5378aa9/autotest/data/meris/mosaic_MER_FRS_1P_RGB_reduced/mosaic_ENVISAT-MER_FRS_1PNPDE20060816_090929_000001972050_00222_23322_0058_RGB_reduced.tif -O rgb.tiff
wget https://raw.githubusercontent.com/hubmapconsortium/portal-containers/master/containers/ome-tiff-offsets/test-input/multi-channel.ome.tif -O multi-channel.ome.tif
gdal_translate -of GTiff initial.tiff stripped.tiff
gdal_translate -of GTiff -co TILED=YES -co BLOCKXSIZE=32 -co BLOCKYSIZE=32 stripped.tiff tiled.tiff
gdal_translate -of GTiff -ot Int32 stripped.tiff int32.tiff
gdal_translate -of GTiff -ot UInt32 stripped.tiff uint32.tiff
gdal_translate -of GTiff -ot Float32 stripped.tiff float32.tiff
gdal_translate -of GTiff -ot Float64 stripped.tiff float64.tiff
gdal_translate -of GTiff -co COMPRESS=LZW stripped.tiff lzw.tiff
gdal_translate -of GTiff -co COMPRESS=DEFLATE stripped.tiff deflate.tiff
gdal_translate -of GTiff -co COMPRESS=DEFLATE -co PREDICTOR=2 stripped.tiff deflate_predictor.tiff
gdal_translate -of GTiff -co COMPRESS=DEFLATE -co PREDICTOR=2 -co BLOCKYSIZE=128 stripped.tiff deflate_predictor_big_strips.tiff
gdal_translate -of GTiff -co TILED=YES -co BLOCKXSIZE=32 -co BLOCKYSIZE=32 -co COMPRESS=DEFLATE -co PREDICTOR=2 stripped.tiff deflate_predictor_tiled.tiff
gdal_translate -of GTiff -co COMPRESS=PACKBITS stripped.tiff packbits.tiff
gdal_translate -of GTiff -co INTERLEAVE=BAND stripped.tiff interleave.tiff
gdal_translate -of GTiff -co TILED=YES -co BLOCKXSIZE=32 -co BLOCKYSIZE=32 -co INTERLEAVE=BAND stripped.tiff tiledplanar.tiff
gdal_translate -of GTiff -co COMPRESS=LZW -co TILED=YES -co BLOCKXSIZE=32 -co BLOCKYSIZE=32 -co INTERLEAVE=BAND stripped.tiff tiledplanarlzw.tiff
gdal_translate -of GTiff -co COMPRESS=LZW -ot Float64 stripped.tiff float64lzw.tiff
gdal_translate -of GTiff -co COMPRESS=LZW -co PREDICTOR=2 stripped.tiff lzw_predictor.tiff
gdal_translate -of GTiff -outsize 10% 10% stripped.tiff small.tiff
gdal_translate -of GTiff -co BIGTIFF=YES stripped.tiff bigtiff.tiff
gdal_translate -of GTiff -co COMPRESS=LERC -co MAX_Z_ERROR=1000 stripped.tiff lerc.tiff
gdal_translate -of GTiff -co COMPRESS=LERC -co MAX_Z_ERROR=1000 -co INTERLEAVE=BAND stripped.tiff lerc_interleave.tiff
gdal_translate -of GTiff -co COMPRESS=LERC_DEFLATE -co MAX_Z_ERROR=1000 stripped.tiff lerc_deflate.tiff
gdal_translate -of GTiff -co COMPRESS=LERC_ZSTD -co MAX_Z_ERROR=1000 stripped.tiff lerc_zstd.tiff
gdal_translate -of GTiff -ot Float32 -co COMPRESS=LERC -co MAX_Z_ERROR=1000 stripped.tiff float32lerc.tiff
gdal_translate -of GTiff -ot Float32 -co COMPRESS=LERC -co MAX_Z_ERROR=1000 -co INTERLEAVE=BAND stripped.tiff float32lerc_interleave.tiff
gdal_translate -of GTiff -ot Float32 -co COMPRESS=LERC_DEFLATE -co MAX_Z_ERROR=1000 stripped.tiff float32lerc_deflate.tiff
gdal_translate -of GTiff -ot Float32 -co COMPRESS=LERC_ZSTD -co MAX_Z_ERROR=1000 stripped.tiff float32lerc_zstd.tiff
gdal_translate -of COG initial.tiff cog.tiff
# overviews
cp stripped.tiff overviews.tiff
gdaladdo overviews.tiff 2 4 8 16
cp stripped.tiff overviews_external.tiff
gdaladdo -ro overviews_external.tiff 2 4 8 16
# bigtiff
wget http://www.awaresystems.be/imaging/tiff/bigtiff/BigTIFFSamples.zip
unzip -o BigTIFFSamples.zip -d .
rm BigTIFFSamples.zip
# color images
rgb2pct.py rgb.tiff rgb_paletted.tiff
# convert rgb.tiff -colorspace YCbCr ycbcr.tif
# rgb2ycbcr rgb.tiff ycbcr.tif -h 1 -v 1
gdal_translate -co PHOTOMETRIC=YCBCR -co COMPRESS=JPEG -co JPEG_QUALITY=100 rgb.tiff ycbcr.tif
convert rgb.tiff -colorspace CMYK cmyk.tif
convert rgb.tiff -colorspace Lab cielab.tif
gdal_translate -of GTiff -co COMPRESS=JPEG rgb.tiff jpeg.tiff
gdal_translate -of GTiff -co COMPRESS=JPEG -co PHOTOMETRIC=YCBCR rgb.tiff jpeg_ycbcr.tiff
# modeltransformation tag
#wget https://s3.amazonaws.com/wdt-external/no_pixelscale_or_tiepoints.tiff
# RGBA example
wget https://s3.eu-central-1.amazonaws.com/waterview.geotiff/RGBA.tiff
# special LZW file
wget https://github.com/geotiffjs/geotiff.js/files/4186628/nasa_raster.tiff.zip
unzip -o nasa_raster.tiff.zip -d .
# additional test for LZW: EOI_CODE after CLEAR_CODE
wget https://github.com/geotiffjs/geotiff.js/files/2378479/lzw.zip
mkdir -p lzw_clear_eoi
unzip -o lzw.zip -d lzw_clear_eoi
# n-bit support
for i in 10 11 12 13 14 15; do
gdal_translate -of GTiff -co NBITS=$i -ot UInt16 initial.tiff n_bit_${i}.tiff || true
gdal_translate -of GTiff -co NBITS=$i -co TILED=YES -ot UInt16 initial.tiff n_bit_tiled_${i}.tiff || true
gdal_translate -of GTiff -co NBITS=$i -ot UInt16 -co INTERLEAVE=BAND initial.tiff n_bit_interleave_${i}.tiff || true
done
gdal_translate -of GTiff -co NBITS=16 -ot Float32 initial.tiff float_n_bit_16.tiff || true
gdal_translate -of GTiff -co NBITS=16 -ot Float32 -co TILED=YES initial.tiff float_n_bit_tiled_16.tiff || true
gdal_translate -of GTiff -co NBITS=16 -ot Float32 -co INTERLEAVE=BAND initial.tiff float_n_bit_interleave_16.tiff || true
# GDAL_METADATA support
wget https://github.com/GeoTIFF/test-data/archive/6ec42abc044a6884037c148d67a87a5d28228ce5.zip -O geotiff-test-data.zip
unzip -j -o geotiff-test-data.zip "test-data-*/files/*" -d .
rm geotiff-test-data.zip
# add top-level metadata to a tiff for testing purposes
gdal_edit.py -mo DATUM=WGS84 wind_direction.tif

View file

@ -0,0 +1,261 @@
/* global GeoTIFF:false, plotty:false */
const { Pool, fromUrl } = GeoTIFF;
const imageWindow = [0, 0, 500, 500];
const tiffs = [
'stripped.tiff',
'tiled.tiff',
'interleave.tiff',
'tiledplanar.tiff',
'float32.tiff',
'uint32.tiff',
'int32.tiff',
'float64.tiff',
'lzw.tiff',
'tiledplanarlzw.tiff',
'float64lzw.tiff',
'lzw_predictor.tiff',
'deflate.tiff',
'deflate_predictor.tiff',
'deflate_predictor_tiled.tiff',
'lerc.tiff',
'lerc_interleave.tiff',
'lerc_deflate.tiff',
'float32lerc.tiff',
'float32lerc_interleave.tiff',
'float32lerc_deflate.tiff',
// "n_bit_tiled_10.tiff",
// "n_bit_11.tiff",
// "n_bit_12.tiff",
// "n_bit_13.tiff",
// "n_bit_14.tiff",
// "n_bit_15.tiff",
// "n_bit_interleave_10.tiff",
// "n_bit_interleave_12.tiff",
// "n_bit_interleave_14.tiff",
// "n_bit_interleave_15.tiff",
// "float_n_bit_16.tiff",
// "float_n_bit_tiled_16.tiff",
// "float_n_bit_interleave_16.tiff",
];
const rgbtiffs = [
'stripped.tiff',
'rgb.tiff',
'BigTIFF.tif',
'rgb_paletted.tiff',
'cmyk.tif',
'ycbcr.tif',
'cielab.tif',
'5ae862e00b093000130affda.tif',
'jpeg.tiff',
'jpeg_ycbcr.tiff',
];
const pool = new Pool();
const bandsSelect = document.getElementById('bands');
for (let i = 0; i < 15; ++i) {
const option = document.createElement('option');
option.value = i;
option.text = i + 1;
bandsSelect.appendChild(option);
}
async function render(image, sample, canvas, width, height) {
try {
const data = await image.readRasters({
samples: [sample],
window: imageWindow,
fillValue: 0,
pool,
});
const plot = new plotty.plot(canvas, data[0], width, height, [10, 65000], 'viridis', false); // eslint-disable-line new-cap
plot.render();
} catch (exc) {
// pass
}
}
async function renderRGB(image, canvas, width, height) {
try {
const rgb = await image.readRGB({
window: imageWindow,
pool,
});
const ctx = canvas.getContext('2d');
const imageData = ctx.createImageData(width, height);
const { data } = imageData;
let o = 0;
for (let i = 0; i < rgb.length; i += 3) {
data[o] = rgb[i];
data[o + 1] = rgb[i + 1];
data[o + 2] = rgb[i + 2];
data[o + 3] = 255;
o += 4;
}
ctx.putImageData(imageData, 0, 0);
} catch (exc) {
// pass
}
}
tiffs.forEach(async (filename) => {
const div = document.createElement('div');
div.style.float = 'left';
const header = document.createElement('p');
header.innerHTML = filename;
const canvas = document.createElement('canvas');
canvas.id = filename;
canvas.width = imageWindow[2] - imageWindow[0];
canvas.height = imageWindow[3] - imageWindow[1];
div.appendChild(header);
div.appendChild(canvas);
document.getElementById('canvases').appendChild(div);
const tiff = await fromUrl(`http://localhost:8090/test/data/${filename}`, {
allowFullFile: true,
cache: true,
});
const image = await tiff.getImage();
await render(image, 0, canvas, canvas.width, canvas.height);
bandsSelect.addEventListener('change', () => {
render(image, parseInt(bandsSelect.options[bandsSelect.selectedIndex].value, 10), canvas, canvas.width, canvas.height);
});
});
rgbtiffs.forEach(async (filename) => {
const div = document.createElement('div');
div.style.float = 'left';
const header = document.createElement('p');
header.innerHTML = filename;
const canvas = document.createElement('canvas');
canvas.id = filename;
canvas.width = imageWindow[2] - imageWindow[0];
canvas.height = imageWindow[3] - imageWindow[1];
div.appendChild(header);
div.appendChild(canvas);
document.getElementById('canvases').appendChild(div);
const tiff = await fromUrl(`http://localhost:8090/test/data/${filename}`, {
allowFullFile: true,
cache: true,
});
const image = await tiff.getImage();
await renderRGB(image, canvas, canvas.width, canvas.height);
});
// tiffs.forEach(function (filename) {
// const xhr = new XMLHttpRequest();
// xhr.open('GET', 'data/' + filename, true);
// xhr.responseType = 'arraybuffer';
// const div = document.createElement("div");
// div.style.float = "left";
// const header = document.createElement("p");
// header.innerHTML = filename;
// const canvas = document.createElement("canvas");
// canvas.id = filename;
// canvas.width = 500;
// canvas.height = 500;
// div.appendChild(header);
// div.appendChild(canvas);
// document.getElementById("canvases").appendChild(div);
// xhr.onload = function (e) {
// console.time("readRasters " + filename);
// fromArrayBuffer(this.response)
// .then(parser => parser.getImage())
// .then((image) => {
// // console.log(image);
// // console.log(image.getTiePoints());
// // var imageWindow = null;
// let width = image.getWidth();
// let height = image.getHeight();
// if (imageWindow) {
// width = imageWindow[2] - imageWindow[0];
// height = imageWindow[3] - imageWindow[1];
// }
// let plot;
// bandsSelect.addEventListener("change", function (e) {
// image.readRasters({ samples: [parseInt(bandsSelect.options[bandsSelect.selectedIndex].value)], poolSize: 8 })
// .then(function (rasters) {
// const canvas = document.getElementById(filename);
// plot = new plotty.plot(canvas, rasters[0], width, height, [10, 65000], "viridis", false);
// plot.render();
// });
// });
// image.readRasters({
// samples: [0],
// window: imageWindow,
// fillValue: 0,
// pool,
// })
// .then(function (rasters) {
// console.timeEnd("readRasters " + filename);
// const canvas = document.getElementById(filename);
// plot = new plotty.plot(canvas, rasters[0], width, height, [10, 65000], "viridis", false);
// plot.render();
// });
// });
// };
// xhr.send();
// });
// rgbtiffs.forEach(function (filename) {
// const xhr = new XMLHttpRequest();
// xhr.open('GET', 'data/' + filename, true);
// xhr.responseType = 'arraybuffer';
// const div = document.createElement("div");
// div.style.float = "left";
// const header = document.createElement("p");
// header.innerHTML = filename;
// const canvas = document.createElement("canvas");
// canvas.id = filename;
// div.appendChild(header);
// div.appendChild(canvas);
// document.getElementById("canvases").appendChild(div);
// xhr.onload = function (e) {
// fromArrayBuffer(this.response)
// .then(parser => parser.getImage())
// .then((image) => {
// console.time("readRGB " + filename);
// image.readRGB({ pool }).then(function (raster) {
// console.timeEnd("readRGB " + filename);
// canvas.width = image.getWidth();
// canvas.height = image.getHeight();
// const ctx = canvas.getContext("2d");
// const imageData = ctx.createImageData(image.getWidth(), image.getHeight());
// const data = imageData.data;
// let o = 0;
// for (var i = 0; i < raster.length; i += 3) {
// data[o] = raster[i];
// data[o + 1] = raster[i + 1];
// data[o + 2] = raster[i + 2];
// data[o + 3] = 255;
// o += 4;
// }
// ctx.putImageData(imageData, 0, 0);
// });
// });
// };
// xhr.send();
// });

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,11 @@
<html>
<head>
</head>
<body>
<div id="canvases"></div>
<select id="bands"></select>
<script src="../dist-browser/geotiff.js"></script>
<script src="./dev.js"></script>
<script src="lib/plotty.min.js"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,87 @@
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
proxy_force_ranges on;
max_ranges 10;
location / {
max_ranges 10;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
#
# Om nom nom cookies
#
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' '*';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' '*';
add_header 'Access-Control-Expose-Headers' '*';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' '*';
add_header 'Access-Control-Allow-Headers' '*';
add_header 'Access-Control-Expose-Headers' '*';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' '*';
add_header 'Access-Control-Allow-Headers' '*';
add_header 'Access-Control-Expose-Headers' '*';
}
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}

View file

@ -0,0 +1,38 @@
/* eslint-disable global-require, no-unused-expressions */
import isNode from 'detect-node';
import { expect } from 'chai';
import { makeFetchSource } from '../src/source/remote.js';
const port = 9999;
let server = null;
before(() => {
if (isNode) {
const express = require('express');
const app = express();
app.use(express.static('.'));
server = app.listen(9999);
}
});
after(() => {
if (server) {
server.close();
}
});
describe('makeFetchSource', () => {
it('shall fetch the first n bytes', async () => {
const blockSize = 512;
const source = makeFetchSource(`http://localhost:${port}/test/data/stripped.tiff`, { blockSize });
expect(source).to.be.ok;
const response = await source.fetch(0, 10);
expect(response.byteLength).to.equal(10);
const firstBlock = source.blocks.get(0);
expect(firstBlock).to.be.ok;
expect(firstBlock.offset).to.equal(0);
expect(firstBlock.length).to.equal(blockSize);
expect(firstBlock.data.byteLength).to.equal(blockSize);
});
});