Rotate a sphere in three.js in order to align the mapped image of the globe with the GeoJSON data that is displayed in the same three

I have successfully implemented a globe in three.js with an image mapped onto the sphere.

Furthermore, I am utilizing the ThreeGeoJSON library to visualize geojson data on top of the globe.

However, the geographies from the geojson data do not align correctly. https://i.sstatic.net/nNjvz.png

To address this issue, I need to rotate the globe along with the mapped image so that they match up. Despite trying to set a quaternion variable and rotating based on it, I have been unsuccessful in achieving the desired alignment. Any assistance or guidance would be greatly appreciated.

You can view a functional version of my current progress at: http://bl.ocks.org/jhubley/8450d7b0df0a4a9fd8ce52d1775515d5

Access all the code, images, and data here: https://gist.github.com/jhubley/8450d7b0df0a4a9fd8ce52d1775515d5

Additionally, I have included the index.html below:

    <html>
        <head>
            <title>ThreeGeoJSON</title>

            <script src="threeGeoJSON.js"></script>

            <!-- Three.js library, movement controls, and jquery for the geojson-->
            <script src="three.min.js"></script>
            <script src="TrackballControls.js"></script>
            <script src="jquery-1.10.2.min.js"></script>
        </head>
        <body>
        <script type="text/JavaScript">
              var width  = window.innerWidth,
                height = window.innerHeight;

              // Earth params
              var radius   = 9.99,
                segments = 32,
                rotation = 0 ;

                //New scene and camera
                var scene = new THREE.Scene();
                var camera = new THREE.PerspectiveCamera(55, width / height, 0.01, 1000);
                camera.position.z = 1;
                camera.position.x = -.2;
                camera.position.y = .5;

                //New Renderer
                var renderer = new THREE.WebGLRenderer();
                renderer.setSize(width, height);
                document.body.appendChild(renderer.domElement);

                //Add lighting
                scene.add(new THREE.AmbientLight(0x333333));

                var light = new THREE.DirectionalLight(0xe4eef9, .7);
                light.position.set(12,12,8);
                scene.add(light);

                var quaternion = new THREE.Quaternion();
                quaternion.setFromAxisAngle( new THREE.Vector3( 0, 1, 0 ), Math.PI / 2 );



                var sphere = createSphere(radius, segments);
                //sphere.rotation.y = rotation;
                sphere.rotation = new THREE.Euler().setFromQuaternion( quaternion );

                scene.add(sphere)

                //Create a sphere to make visualization easier.
                var geometry = new THREE.SphereGeometry(10, 32, 32);
                var material = new THREE.MeshPhongMaterial({
                    //wireframe: true,
                    //transparent: true
                });

                function createSphere(radius, segments) {
                  return new THREE.Mesh(
                    new THREE.SphereGeometry(radius, segments, segments),
                    new THREE.MeshPhongMaterial({
                      map:         THREE.ImageUtils.loadTexture('relief.jpg'),
                      bumpMap:     THREE.ImageUtils.loadTexture('elev_bump_4k.jpg'),
                      bumpScale:   0.005,
                      specularMap: THREE.ImageUtils.loadTexture('wateretopo.png'),
                      specular:    new THREE.Color('grey')
                    })
                  );
                }

                var clouds = createClouds(radius, segments);
                clouds.rotation.y = rotation;
                scene.add(clouds)

                function createClouds(radius, segments) {
                  return new THREE.Mesh(
                    new THREE.SphereGeometry(radius + .003, segments, segments),
                    new THREE.MeshPhongMaterial({
                      map:         THREE.ImageUtils.loadTexture('n_amer_clouds.png'),
                      transparent: true
                    })
                  );
                }

                //Draw the GeoJSON
                var test_json = $.getJSON("countries_states.geojson", function(data) {

                    drawThreeGeo(data, 10, 'sphere', {
                        color: 'red'
                    })
                });

                //Draw the GeoJSON loggerhead data
                var test_json = $.getJSON("loggerhead-distro-cec-any.json", function(data) {
                    drawThreeGeo(data, 10, 'sphere', {
                        color: 'blue'
                    })
                });

                //Set the camera position
                camera.position.z = 30;

                //Enable controls
                var controls = new THREE.TrackballControls(camera);

                //Render the image
                function render() {
                    controls.update();
                    requestAnimationFrame(render);
                    renderer.render(scene, camera);
                }

                render();
            </script>
      </body>
    </html>

Answer №1

Instead of using the old version r66, I decided to switch to r81 by simply replacing the three.min.js file. I made some modifications to your createSphere() function and it appears to be functioning properly.

        function createSphere(radius, segments) {
            var sphereGeometry = new THREE.SphereGeometry(radius, segments, segments);
            sphereGeometry.rotateY(THREE.Math.degToRad(-90));
            return new THREE.Mesh(
                sphereGeometry,
                new THREE.MeshPhongMaterial({
                    map:         new THREE.TextureLoader().load('relief.jpg'),
                    bumpMap:     new THREE.TextureLoader().load('elev_bump_4k.jpg'),
                    bumpScale:   0.005,
                    specularMap: new THREE.TextureLoader().load('wateretopo.png'),
                    specular:    new THREE.Color('grey')
                })
            );
        }

The only adjustment I made was rotating the geometry of the sphere around the Y-axis at -90 degrees. You can view the result here

https://i.sstatic.net/KVsYM.png

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

What is the most efficient method for designing this jQuery code to be reusable?

I am currently using dynamic Bootstrap popovers that are populated with content from my database. In PHP, it generates unique classes for each popover. My question is, when using jQuery, do I need to trigger the popovers individually? This is how I am cur ...

What is the best way to set up TypeScript to utilize multiple node_modules directories in conjunction with the Webpack DLL plugin?

Utilizing Webpack's DllPlugin and DllReferencePlugin, I create a distinct "vendor" bundle that houses all of my main dependencies which remain relatively static. The project directory is structured as follows: project App (code and components) ...

Testing the updated version 18 of Create React APP index.js using Jest

Previously, I had this index.js file created for React version <= 17. import React from 'react'; import ReactDOM from 'react-dom'; import App from './views/App'; import reportWebVitals from './reportWebVitals'; im ...

Collaborate on global functions across the Quasar ecosystem and beyond, including Vue3

Is it plausible to utilize this method for sharing functionality (not data, which is handled by stores) in a Quasar and Vue3 application? // boot/generic_stuff.js import {boot} from 'quasar/wrappers' const function_list = { /* content goes here ...

Tips on effectively rendering child components conditionally in React

My components currently consist of an AddBookPanel containing the AddBookForm. I am looking to implement a feature where the form is displayed upon clicking the 'AddBookButton', and hidden when the 'x' button (image within AddBookForm c ...

"Emphasize menu items with an underline as you navigate through the

I am using Gatsby with React and have a navigation menu with links. I would like to make it so that when a link is clicked, a border bottom appears to indicate the current page, rather than only on hover. <ul className="men" id="menu"> ...

Is Storybook webpack stuck in a loop, rebuilding and reloading constantly?

While working on a NextJS project with Storybook, I am encountering a recurring issue where the webpack keeps rebuilding continuously without stopping. This relentless rebuilding process puts a strain on my CPU and drains the battery of my device. Even aft ...

Preventing Bull Queue from automatically re-starting jobs upon server restart

Currently, I am utilizing the bull queue system for processing jobs. Imagine a scenario where a job is in progress with an active status and I restart my development server. Upon restarting the worker script, the job remains in the active state within the ...

Issue with deploying NEXT.JS due to a failure in the build process caused by next lint

Issue I have been encountering deployment failures on Vercel due to lint errors in test files within my git repository. Despite following the recommendations from the Vercel documentation for ESLint settings, the issue persists. According to Vercel' ...

The jQuery script fails to function properly within dynamically loaded content via ajax

After browsing through various articles and seeking help from Google, I've managed to do some basic coding as a designer. However, there's a complex problem that I'm struggling with. On my main page, I have news displayed and when scrolling ...

How to retrieve and delete a row based on the search criteria in an HTML table using jQuery

Here is the HTML code snippet: <table class="table" id="myTable"> <tr> <th>Type</th> <th>Counter</th> <th>Remove</th> <th style="display:none;">TypeDistribution</t ...

What is the most efficient way to perform an array join in Node.js, akin to the speed of MongoDB's $

Looking to implement a $lookup function in Node.js similar to the $lookup aggregation in MongoDB. I have a solution in mind, but I'm unsure about its performance when dealing with larger arrays or bigger objects. let users = [ {userId: 1, name: ...

What is the process of combining JS functions with PHP echo in code?

I am currently working on creating a popout menu for an array of values that are being displayed from the database. The goal is to show the corresponding popout menu when the svg is clicked, but I am running into an issue where it only works for the first ...

Live Search: Find Your Answers with Ajax

I've come across this issue multiple times, but haven't found a solution that fits my specific requirements. I've encountered several URLs with links like example.com/ajax/search?query=Thing I'm currently working on a header and using ...

Unresponsive Radio Buttons in HTML

Have you ever encountered the issue where you can't seem to select radio buttons despite them having a confirmed name attribute? Here is an example of the HTML code: <div id="surveys-list" class="inline col-xs-12"><div> <div class="i ...

What is the best way to enable an image to be moved on top of another image?

Is there a way to allow users to drag around an image that is positioned on top of another image in an HTML file? I want the superimposed image to stay within the boundaries of the underlying image. Any suggestions on how this can be achieved? <html& ...

Guide: Generating a DIV Element with DOM Instead of Using jQuery

Generate dynamic and user-defined positioning requires input parameters: offsetHeight, offsetLeft, offsetParent, offsetTop, offsetWidth ...

UI-grid: Triggering a modal window from the filter header template

Is there a way to create a filter that functions as a simple modal window triggered by a click event, but can be displayed on top of a grid when placed within the filterHeaderTemplate? I have encountered an issue where the modal window I created is being ...

Execute the second method once the first method has completed its execution

As I develop my npm package, I am faced with the challenge of ensuring that one method waits for another to complete before executing. For example: var package = require('myNpmPackage'); package.method1(options); ... Later on, possibly in a dif ...

Issue with hook not updating when invoked inside useEffect

I'm encountering an issue with updating the state after fetching data from my API. The API response seems to be correct, but for some reason, my weatherData-hook is not getting updated and it returns undefined. Can anyone point out what mistake I migh ...