The function d3.geoStitch has not been defined

I am currently working on implementing this example that visualizes a TIFF file using d3 as a node script.

Everything seems to be functioning well, except when it comes to d3.geoStitch where my script throws an error stating d3.geoStitch is undefined. The geoStitch function belongs to d3-geo-projection, which I have already installed:

{
  "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"
  }
}

The complete script is as follows:

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) {
    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) {
    const shared = {};

    let 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();
            })
        }))
    }

    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;
        })
    });

    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();

Is there a way to resolve the issue with geoStitch not being recognized?

Answer №1

The issue occurred due to a problem with importing d3 library.

Below is the updated code that should be used:

import * as fs from "fs";
import GeoTiff, { fromArrayBuffer, fromUrl, fromFile } from "geotiff";
import { scaleSequential } from "d3-scale";
const d3 = await Promise.all([
    import("d3-format"),
    import("d3-geo"),
    import("d3-geo-projection"),
    import("d3"),
  ]).then(d3 => Object.assign({}, ...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) {
    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) {

    const shared = {};

    let 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();
            })
        }))
    }

    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;
        })
    });

    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();

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Building an easy-to-use jQuery task list

I'm currently working on a basic to-do list in Javascript, but I've encountered an issue. When I check the checkbox, the style of the adjacent text doesn't change as expected. Instead, it's the heading text that is affected by the chang ...

What could be causing my newsletter form to malfunction on Amazon CloudFront?

I'm currently working with HTML on an Amazon EC2 instance (Linux free tier). I want to integrate CloudFront into my setup, but I'm encountering issues with my newsletter functionality. Despite not being an expert in AWS, I am struggling to unders ...

How can you reset a variable counter while inside a forEach loop?

I am currently working on resetting a counter that is part of a recursive forEach loop within my code. Essentially, the code snippet provided calculates the length of the innermost key-value pair as follows: length = (key length) + (some strings inserted) ...

Identical HTML elements appearing across multiple DOM pages

My question might seem silly, but I'm facing an issue. I have several HTML pages such as index.html and rooms.html, along with a main.js file containing scripts for all of these pages. The problem arises because I have variables like const HTMLelemen ...

Alter the hyperlink to a different value based on a specific condition

I need help with implementing a login feature on my app. The idea is that when the user clicks the login button, it should trigger a fetch request to log in with their credentials. If the login is successful, the button's value should change to redire ...

Attempting to save data to an external JSON file by utilizing fs and express libraries

I've encountered a challenge while attempting to serialize an object into JSON. Despite my best efforts, I keep encountering an error that has proven to be quite stubborn... Below is the code snippet that's causing the issue: APP.post('/api ...

There was an error message saying "Unable to locate property 'getElementById' in undefined"

I am facing an issue with a jQuery filter function, and the error message it's showing is: Cannot read property 'getElementById' of undefined function CheckFilter() { var input, filter, table, tr, td, i, searchFilter; input = ...

Is it possible to refresh the chat-box using PHP?

I recently created a chat box application using PHP, but I'm facing an issue with its automatic reload functionality. Is there a way to implement auto-reload in PHP itself, or would it be better to restructure the system to utilize AJAX? Additionally, ...

The function is not triggered when the select tag is changed

I'm currently working on implementing a drop-down menu using the <select> element in HTML. Here is the code snippet I have so far: <select id="Parameter1" onchange="function1()"> <option value = "0105" name = "Frequency">Frequency ...

The Android webview encountered an error: XMLHttpRequest failed to load because the specified Origin <url> is not permitted by Access-Control-Allow-Origin restrictions

I have developed an application that loads an entire website in an Android WebView. The native code in the Android project communicates with the webpage using the Android Jockey Library, and vice versa. Everything is working smoothly except for one instan ...

Issue: Module 'request-promise' not found

I have been trying to execute my nodejs code on Snowflake Server. The code seems fine but I keep encountering the following error: `Error:` Cannot find module 'request-promise' at Function.Module._resolveFilename (internal/modules/cjs/loader.js:6 ...

How can I modify the dot colors on a graph using chart.js?

Need assistance with changing the color of graph data points https://i.sstatic.net/QGJBv.png Here is my JavaScript code snippet I have successfully created a graph using chart.js. However, I now want to differentiate data points by displaying different c ...

Generating a multidimensional associative array based on user inputs from a form

What is the best way to transform form input data into a multidimensional associative array? This is how the form appears: <div id="items"> <h4>Engraving Text</h4> <div class="item" data-position="1"> <h4 id="en ...

Ways to selectively implement the callback of setState using hooks in specific locations, rather than applying it universally

There are times when I need to set a state and perform an action afterwards, but other times not! How can I achieve this using hooks? Sometimes, I want to call a function or do something after setting the state: this.setState({inputValue:'someValue& ...

What is the best way to generate dynamic components on the fly in ReactJS?

Could you please guide me on: Techniques to dynamically create react components, such as from simple objects? Is it possible to implement dynamic creation in JSX as well? Does react provide a method to retrieve a component after its creation, maybe b ...

What is the best way to incorporate a string value from an external file into a variable in TypeScript without compromising the integrity of special characters?

I am encountering an issue with importing a variable from a separate file .ts that contains special characters, such as accents used in languages like French and Spanish. The problem I am facing is that when I require the file, the special characters are ...

What is the relationship between Bower and NPM when they are used together?

As a Java back-end developer transitioning to front-end JavaScript, I'm facing the challenge of setting up testing for our client-side code. While I have experience with server-side Node projects and tools like Maven, I'm relatively new to front- ...

Issue encountered while running React on Mac: Error with ELIFECYCLE, spawn, ENOENT

After successfully creating a tester react file using create-react-app, I encountered errors when trying to run any other react file with "npm start." The errors I received were as follows: > react-scripts start sh: react-scripts: command not found npm ...

Troubleshooting a Problem with AppCheck Firebase reCaptcha Configuration

Currently integrating Firebase with my Next.js project. I've been attempting to configure AppCheck reCaptcha following the documentation and some recommendations, but I encounter an issue when running yarn build The build process fails with the foll ...

Mastering Array Dispatch in VueJS

I've encountered an issue while trying to send an array of data to the backend. I attempted to include [] in the dispatch variables and on the backend, but it only captures the last data sent to the backend. My objective is to associate each data with ...