brianzinn / react-babylonjs

React for Babylon 3D engine
https://brianzinn.github.io/react-babylonjs/
829 stars 105 forks source link

Unable to convert geographic coordinates to 3D vectors efficiently #267

Closed harit-m-kumar closed 1 year ago

harit-m-kumar commented 1 year ago

We are working on a map project, using babylon React library. The latitude , longitude and height input coordinates we get are in the given format.

coOrdinates = { [​118.288232450077743,​-31.773800185627614,​218.92​],​ [​114.288031993802591,​-33.773212105506893,​218.93​],​ [​119.288075541452429,​-32.773211130010566,​218.92​],​ }

We applied the given formulae : pos.x = Math.cos(lat Math.PI / 180) Math.cos(lon Math.PI / 180) radius;​ pos.y = Math.cos(lat Math.PI / 180) Math.sin(lon Math.PI / 180) radius;​ pos.z = Math.sin(lat Math.PI / 180) radius;

Taking Radius as radius of the earth. But we re not getting the correct points in the map. This was recomended for globe/earth model only. Our terrain is flat in an xy plane. Can anyone suggest a work around?

Has anyone faced a similar problem? We are looking for a workaround.

konsumer commented 1 year ago

This is definitely out-of-scope for babylonjs & react-babylonjs, but I seem to remember using this the last time I tried to do something like this (offline lat/long to position, in pixel coordinates, on images.)

konsumer commented 1 year ago

If you have an example project with a map, I can try to apply it. I think when I used the formula, I ignored z and just put it on the surface of the map.

It's essentially this part:

/**
 * @param {number} latitude in degrees
 * @param {number} longitude in degrees
 * @param {number} mapWidth in pixels
 * @param {number} mapHeight in pixels
 */
function latLonToOffsets(latitude, longitude, mapWidth, mapHeight) {
  const radius = mapWidth / (2 * Math.PI);
  const FE = 180; // false easting

  const lonRad = degreesToRadians(longitude + FE);
  const x = lonRad * radius;

  const latRad = degreesToRadians(latitude);
  const verticalOffsetFromEquator =
    radius * Math.log(Math.tan(Math.PI / 4 + latRad / 2));
  const y = mapHeight / 2 - verticalOffsetFromEquator;

  return { x, y };
}

/**
 * @param {number} degrees
 */
function degreesToRadians(degrees) {
  return (degrees * Math.PI) / 180;
}
brianzinn commented 1 year ago

closing from inactivity. please re-open if you would like to discuss further.