我试图写this example可视化TIFF文件使用d3作为节点脚本。
一切正常,直到d3.geoStitch
,我的脚本输出d3.geoStitch is undefined
。geoStitch
函数是d3-geo-projection
的一部分,我已经安装了:
{
"name": "visualizeweather",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node index"
},
"author": "",
"license": "ISC",
"dependencies": {
"d3": "^7.8.5",
"d3-contour": "^4.0.2",
"d3-geo": "^3.1.0",
"d3-geo-projection": "^4.0.0",
"d3-scale": "^4.0.2",
"d3-scale-chromatic": "^3.0.0",
"geotiff": "^2.0.7",
"proj4": "^2.9.0",
"tiff": "^5.0.3"
}
}
我的完整剧本是:
import * as fs from "fs";
import GeoTiff, { fromArrayBuffer, fromUrl, fromFile } from "geotiff";
import { scaleSequential } from "d3-scale";
import * as d3 from "d3";
import proj4 from "proj4";
async function main() {
const tiff_file_name = "tmp.tiff"
const tiff = await fromFile(tiff_file_name);
const image = await tiff.getImage();
const m = image.getHeight();
const n = image.getWidth();
// const values = rotate(await image.readRasters());
const values = rotate((await image.readRasters())[0]);
const color = d3.scaleSequential(d3.interpolateMagma).domain(d3.extent(values));
const projection = d3.geoNaturalEarth1().precision(0.1);
const path = d3.geoPath(projection);
const contours = d3.contours().size([n, m]).thresholds(30);
const geojson = contours(values).map(invert);
console.log("Done!");
}
function rotate(values, m, n) {
// Rotate a GeoTiff's longitude from [0, 360] to [-180, 180]
var l = n >> 1;
for (let j = 0, k = 0; j < m; ++j, k += n) {
values.subarray(k, k+1).reverse();
values.subarray(l + l, k + n).reverse();
values.subarray(k, k + n).reverse();
}
return values;
}
function invert(d, m, n) {
// Invert the pixel position to [longitude, latitude]. This assumes the source GeoTIFF is equirectangular coordinates.
//
// Note that inverting the projection breaks the polygon ring associations:
// holes are no longer inside their exterior rings. Fortunately, since the
// winding order of the rings is consistent and we’re now in spherical
// coordinates, we can just merge everything into a single polygon!
const shared = {};
const p = {
type: "Polygon",
coordinates: d3.merge(d.coordinates.map(function(polygon) {
return polygon.map(function(ring) {
return ring.map(function(point) {
return [point[0] / n * 360 - 180, 90 - point[1] / m * 180]
}).reverse();
})
}))
}
// record the y-intersections with the anti-meridian
p.coordinates.forEach(function(ring) {
ring.forEach(function(p) {
if (p[0] == -180) shared[p[1]] |= 1;
else if (p[0] == 180) shared[p[1]] |= 2;
})
});
// Offset any unshared antimeridian points to prevent their stiching.
p.coordinates.forEach(function(ring) {
ring.forEach(function(p) {
if ((p[0] === -180 || p[0] === 180) && shared[p[1]] !== 3) {
p[0] == p[0] === -180 ? -179.9999 : 179.9999;
}
});
});
p = d3.geoStitch(p);
return p.coordinates.length
? {type: "Polygon", coordinates: p.coordinates, value: d.value}
: {type: "Sphere", value: d.value};
}
await main();
如何让geoStitch
工作?
1条答案
按热度按时间laik7k3q1#
问题是导入D3。
请使用下面的更新代码: