1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
|
import fs from 'fs'; import * as GeoTIFF from 'geotiff'; import proj4 from 'proj4'; import { createCanvas } from 'canvas';
async function parseGeoTIFF(filePath: string) { const buffer = fs.readFileSync(filePath);
const tiff = await GeoTIFF.fromArrayBuffer(buffer.buffer); const image = await tiff.getImage();
const width = image.getWidth(); const height = image.getHeight();
const tiePoints = image.getTiePoints(); const scale = image.getFileDirectory().ModelPixelScale; if (!tiePoints.length || !scale) { throw new Error('Missing geo-referencing tags (tie points or pixel scale)'); } const { x: originX, y: originY } = tiePoints[0]; const [pixelSizeX, pixelSizeY] = scale;
const minX = originX; const maxY = originY; const maxX = originX + width * pixelSizeX; const minY = originY - height * pixelSizeY;
const geoKeys = image.getGeoKeys(); const epsgCode = geoKeys.ProjectedCSTypeGeoKey || geoKeys.GeographicTypeGeoKey; const sourceCrs = EPSG:${epsgCode};
const transformer = proj4(sourceCrs, 'EPSG:4326'); const [minLon, minLat] = transformer.forward([minX, minY]); const [maxLon, maxLat] = transformer.forward([maxX, maxY]);
const rastersRaw = await image.readRasters({ interleave: true }); const rasterData = rastersRaw instanceof Uint8ClampedArray ? rastersRaw : new Uint8ClampedArray(rastersRaw as any);
const canvas = createCanvas(width, height); const ctx = canvas.getContext('2d'); const imgData = ctx.createImageData(width, height); imgData.data.set(rasterData); ctx.putImageData(imgData, 0, 0);
const outPath = filePath.replace(/\.(tif|tiff)$/i, '.png'); fs.writeFileSync(outPath, canvas.toBuffer('image/png'));
return { width, height, sourceCrs, bboxSource: { minX, minY, maxX, maxY }, bboxLatLng: { minLat, minLon, maxLat, maxLon }, geoKeys, png: outPath }; }
(async () => { try { const result = await parseGeoTIFF(process.argv[2]); console.log('Parsed GeoTIFF metadata:'); console.log(JSON.stringify(result, null, 2)); } catch (err) { console.error('Error parsing GeoTIFF:', err); } })();
|