Adding an object to the Earth given its long/lat

I’ve used three.js to build an Earth with a flyby animation. I’m trying to place an object on the Earth, given a set of longitude and latitude coordinates. I’ve been closely examining this code on JSFiddle, which in fact does what I want. In my case, I’m trying to add a ground station to the Earth, to no avail.

Each time I inspect the console, I see the Earth has a “children” array that includes a GroundStation, which includes the source of the sprite I’m trying to use as the image. However, nothing shows up on the screen. I’ve tried to scale the ground station to enormous proportions just to be able to see it but I cannot see it on the screen. How do I get this image added to the screen at the correct location and get it to actually show up?

Here is the GroundStation code:

import * as THREE from 'three';

export class GroundStation extends THREE.Object3D {

  name: string;

  // fields for visualization
  position: THREE.Vector3;
  raycaster: THREE.Raycaster;
  scene: THREE.Scene;
  sprite: THREE.Sprite;
  geometry: THREE.Geometry;

  constructor() {
    super();

    this.name = 'GroundStation';
    const map = new THREE.TextureLoader().load('assets/images/icon_radar.png');
    const spmaterial = new THREE.SpriteMaterial({ map: map, color: 0xffffff });
    this.sprite = new THREE.Sprite(spmaterial);
    this.sprite.scale.set(20, 10, 10);

    this.add(this.sprite);
  }

}

This is called from the Earth method, ‘addGroundStation’:

  addGroundStation(lat: number, long: number) {
    const gs = new GroundStation();

    const latRad = lat * (Math.PI / 180);
    const lonRad = -long * (Math.PI / 180);
    const r = 10;

    gs.position.set(Math.cos(latRad) * Math.cos(lonRad) * r, Math.sin(latRad) * r, Math.cos(latRad) * Math.sin(lonRad) * r);
    gs.rotation.set(0.0, -lonRad, latRad - Math.PI * 0.5);
    console.log(gs);
    this.groundStations.push(gs);
    this.add(gs);
  }

And the Earth class is used when I create a new instance of the earth in the Home Component:

    this.earth = new Earth();
    // add Groundstation
    this.earth.addGroundStation(40.712700, -74.005900); // New York (Testing)
    console.log(this.earth);
    this.scene.add(this.earth.model);

I’ve been on this for two days I cannot find the reason the ground station is not showing up. Any help is greatly appreciated!

Hi!
Maybe this post will be helpful: Azimuth, polar and radius from xyz

I believe my math is correct but nothing shows up on the globe. In your example you are adding both the globe and line to the scene via scene.add(). I want to avoid doing that so that I can add an object as a child of the Earth. In doing so, the object should rotate with the Earth.

I can add the line to the globe and get the same result (I’ve changed the example).
Any chance to provide an editable live code example, showing the problem?

Actually, I found the issue, upon which lead to a new issue. I was creating the earthGeometry and then earthMaterial separately and then combining them together in Earth.model. So, when calling the addGroundStation code I needed to use this(referring to the earth instance).model.addGroundStation. I was forgetting the model part.

However, now the cone and sphere used to indicate markers on the globe are showing up in two different places. The sphere is above the location and the cone is below the location, given by the long/lat coordinates.

I have no idea what is causing that to happen.

@EssenceOfChaos It’s hard to imagine what’s going on in your scene. Can you show at least an explanatory picture?

If you make Earth an Object3D or Group subclass and add the earth.model mesh and the ground stations and markers as children, any local transform of earth.model will not affect the other components. Just remember to add the parent object (earth or whatever it is called) to the scene.