Skip to content

Commit

Permalink
Add geo utils (#351)
Browse files Browse the repository at this point in the history
* Export constants, add geoutils

* Update geo utils
  • Loading branch information
gkjohnson committed Jun 6, 2023
1 parent 25e422b commit c8eb6a8
Show file tree
Hide file tree
Showing 11 changed files with 62 additions and 68 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"root": true,
"parserOptions": {
"ecmaVersion": 2018
"ecmaVersion": 2020
},

"extends": ["plugin:jest/recommended", "./node_modules/eslint-config-mdcs/index.js"],
Expand Down
19 changes: 10 additions & 9 deletions example/googleMapsExample.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DebugTilesRenderer as TilesRenderer } from '../src/index.js';
import { DebugTilesRenderer as TilesRenderer, GeoUtils, WGS84_ELLIPSOID, WGS84_RADIUS } from '../src/index.js';
import {
Scene,
DirectionalLight,
Expand All @@ -7,6 +7,7 @@ import {
PerspectiveCamera,
Raycaster,
Box3,
MathUtils,
} from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
Expand All @@ -16,7 +17,6 @@ import Stats from 'three/examples/jsm/libs/stats.module.js';

import { MapControls } from './src/lib/MapControls.js';
import { MapsTilesCredits } from './src/MapsTilesCredits.js';
import * as GeoUtils from './src/GeoUtils.js';

const apiOrigin = 'https://tile.googleapis.com';

Expand Down Expand Up @@ -269,7 +269,7 @@ function onWindowResize() {
function updateControls() {

const raycaster = new Raycaster();
raycaster.ray.origin.copy( controls.target ).normalize().multiplyScalar( GeoUtils.WGS84_RADIUS * 1.5 );
raycaster.ray.origin.copy( controls.target ).normalize().multiplyScalar( WGS84_RADIUS * 1.5 );
raycaster.ray.direction.copy( raycaster.ray.origin ).normalize().multiplyScalar( - 1 );
raycaster.firstHitOnly = true;

Expand All @@ -280,7 +280,7 @@ function updateControls() {

} else {

controls.target.normalize().multiplyScalar( GeoUtils.WGS84_RADIUS );
controls.target.normalize().multiplyScalar( WGS84_RADIUS );

}
controls.panPlane.copy( controls.target ).normalize();
Expand All @@ -305,7 +305,10 @@ function updateHash() {
const pos = controls.target.clone();
GeoUtils.swapToGeoFrame( pos );

GeoUtils.WGS84_ELLIPSOID.getPositionToCartographic( pos, res );
WGS84_ELLIPSOID.getPositionToCartographic( pos, res );

res.lat *= MathUtils.RAD2DEG;
res.lon *= MathUtils.RAD2DEG;
window.history.replaceState( undefined, undefined, `#${ res.lat.toFixed( 4 ) },${ res.lon.toFixed( 4 ) }` );

}
Expand All @@ -314,15 +317,14 @@ function initFromHash() {

const hash = window.location.hash.replace( /^#/, '' );
const tokens = hash.split( /,/g ).map( t => parseFloat( t ) );
console.log( tokens );
if ( tokens.length !== 2 || tokens.findIndex( t => Number.isNaN( t ) ) !== - 1 ) {

return;

}

const [ lat, lon ] = tokens;
GeoUtils.WGS84_ELLIPSOID.getCartographicToPosition( lat, lon, 0, controls.target );
WGS84_ELLIPSOID.getCartographicToPosition( lat * MathUtils.DEG2RAD, lon * MathUtils.DEG2RAD, 0, controls.target );
GeoUtils.swapToThreeFrame( controls.target );

updateControls();
Expand Down Expand Up @@ -422,9 +424,8 @@ function render() {
const mat = tiles.group.matrixWorld.clone().invert();
const vec = camera.position.clone().applyMatrix4( mat );


const res = {};
GeoUtils.WGS84_ELLIPSOID.getPositionToCartographic( vec, res );
WGS84_ELLIPSOID.getPositionToCartographic( vec, res );
document.getElementById( 'credits' ).innerText = GeoUtils.toLatLonString( res.lat, res.lon ) + '\n' + credits.getCredits();

}
Expand Down
2 changes: 2 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export { GLTFCesiumRTCExtension } from './three/GLTFCesiumRTCExtension';
export { GLTFExtensionLoader } from './three/GLTFExtensionLoader';
export { Ellipsoid } from './three/math/Ellipsoid';
export { EllipsoidRegion } from './three/math/EllipsoidRegion';
export * as GeoUtils from './three/math/GeoUtils';
export * from './three/math/GeoConstants';

export { TilesRendererBase } from './base/TilesRendererBase';
export { Tile } from './base/Tile';
Expand Down
4 changes: 4 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export {
RANDOM_NODE_COLOR,
CUSTOM_COLOR,
} from './three/DebugTilesRenderer.js';

export { TilesRenderer } from './three/TilesRenderer.js';
export { B3DMLoader } from './three/B3DMLoader.js';
export { PNTSLoader } from './three/PNTSLoader.js';
Expand All @@ -22,13 +23,16 @@ export { EllipsoidRegionHelper, EllipsoidRegionLineHelper } from './three/object
export { SphereHelper } from './three/objects/SphereHelper.js';
export { Ellipsoid } from './three/math/Ellipsoid.js';
export { EllipsoidRegion } from './three/math/EllipsoidRegion.js';
export * as GeoUtils from './three/math/GeoUtils.js';
export * from './three/math/GeoConstants.js';

export { TilesRendererBase } from './base/TilesRendererBase.js';
export { LoaderBase } from './base/LoaderBase.js';
export { B3DMLoaderBase } from './base/B3DMLoaderBase.js';
export { I3DMLoaderBase } from './base/I3DMLoaderBase.js';
export { PNTSLoaderBase } from './base/PNTSLoaderBase.js';
export { CMPTLoaderBase } from './base/CMPTLoaderBase.js';
export * from './base/constants.js';

export { LRUCache } from './utilities/LRUCache.js';
export { PriorityQueue } from './utilities/PriorityQueue.js';
45 changes: 2 additions & 43 deletions src/three/math/Ellipsoid.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,5 @@
import { Vector3, Spherical } from 'three';

// Cesium / 3D tiles Spheroid:
// - Up is Z at 90 degrees latitude
// - 0, 0 latitude, longitude is X axis
// Z
// |
// |
// .----- Y
// /
// X


// Three.js Spherical Coordinates
// - Up is Y at 90 degrees latitude
// - 0, 0 latitude, longitude is Z
// Y
// |
// |
// .----- X
// /
// Z

function swapFrame( target ) {

const { x, y, z } = target;
target.x = z;
target.y = x;
target.z = y;

}

export function sphericalPhiToLatitude( phi ) {

return - ( phi - Math.PI / 2 );

}

export function latitudeToSphericalPhi( latitude ) {

return - latitude + Math.PI / 2;

}
import { swapToGeoFrame, latitudeToSphericalPhi } from './GeoUtils.js';

const _spherical = new Spherical();
const _norm = new Vector3();
Expand Down Expand Up @@ -99,7 +58,7 @@ export class Ellipsoid {
target.setFromSpherical( _spherical ).normalize();

// swap frame from the three.js frame to the geo coord frame
swapFrame( target );
swapToGeoFrame( target );
return target;

}
Expand Down
3 changes: 3 additions & 0 deletions src/three/math/GeoConstants.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { Ellipsoid } from './Ellipsoid';

export const WGS84_ELLIPSOID : Ellipsoid;
4 changes: 4 additions & 0 deletions src/three/math/GeoConstants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { WGS84_RADIUS, WGS84_HEIGHT } from '../../base/constants.js';
import { Ellipsoid } from './Ellipsoid.js';

export const WGS84_ELLIPSOID = new Ellipsoid( WGS84_RADIUS, WGS84_RADIUS, WGS84_HEIGHT );
9 changes: 9 additions & 0 deletions src/three/math/GeoUtils.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Vector3 } from 'three';

export function swapToGeoFrame( target : Vector3 ) : Vector3;

export function swapToThreeFrame( target : Vector3 ) : Vector3;

export function sphericalPhiToLatitude( phi : Number ) : Number;

export function latitudeToSphericalPhi( latitude : Number ) : Number;
36 changes: 24 additions & 12 deletions example/src/GeoUtils.js → src/three/math/GeoUtils.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
import { Spherical, Vector3, MathUtils } from 'three';
import { Ellipsoid } from '../../';

const _spherical = new Spherical();
const _vec = new Vector3();
const _geoResults = {};

export const WGS84_RADIUS = 6378137;

export const WGS84_FLATTENING = 1 / 298.257223563;

export const WGS84_HEIGHT = - ( WGS84_FLATTENING * WGS84_RADIUS - WGS84_RADIUS );

export const WGS84_ELLIPSOID = new Ellipsoid( WGS84_RADIUS, WGS84_RADIUS, WGS84_HEIGHT );
// Cesium / 3D tiles Spheroid:
// - Up is Z at 90 degrees latitude
// - 0, 0 latitude, longitude is X axis
// Z
// |
// |
// .----- Y
// /
// X


// Three.js Spherical Coordinates
// - Up is Y at 90 degrees latitude
// - 0, 0 latitude, longitude is Z
// Y
// |
// |
// .----- X
// /
// Z

export function swapToGeoFrame( target ) {

Expand Down Expand Up @@ -43,7 +55,7 @@ export function latitudeToSphericalPhi( latitude ) {

}

export function correctGeoCoordWrap( lat, lon, target = {} ) {
function correctGeoCoordWrap( lat, lon, target = {} ) {

_spherical.theta = lon;
_spherical.phi = latitudeToSphericalPhi( lat );
Expand All @@ -69,7 +81,7 @@ function toHoursMinutesSecondsString( value, pos = 'E', neg = 'W' ) {
const secDec = ( minDec - minutes ) * 60;
const seconds = ~ ~ secDec;

return `${ hours }° ${ minutes }' ${ seconds }" ${ direction }`
return `${ hours }° ${ minutes }' ${ seconds }" ${ direction }`;

}

Expand All @@ -79,8 +91,8 @@ export function toLatLonString( lat, lon, decimalFormat = false ) {
let latString, lonString;
if ( decimalFormat ) {

latString = `${ ( MathUtils.RAD2DEG * result.lat ).toFixed( 4 ) }°`;
lonString = `${ ( MathUtils.RAD2DEG * result.lon ).toFixed( 4 ) }°`;
latString = `${ ( MathUtils.RAD2DEG * result.lat ).toFixed( 4 ) }°`;
lonString = `${ ( MathUtils.RAD2DEG * result.lon ).toFixed( 4 ) }°`;

} else {

Expand Down
5 changes: 2 additions & 3 deletions test/Ellipsoid.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable jest/expect-expect */
import * as Cesium from 'cesium';
import { Vector3, MathUtils, Matrix4, Box3, Sphere } from 'three';
import { EllipsoidRegion } from '../src/three/math/EllipsoidRegion.js';
Expand Down Expand Up @@ -48,17 +49,15 @@ describe( 'Ellipsoid', () => {
let v, c, c2;
let c_unitEllipse, unitEllipse;
let c_wgsEllipse, wgsEllipse;
let norm, norm2, cnorm, cnorm2;
let norm, cnorm;
beforeEach( () => {

c = new Cesium.Cartesian3();
c2 = new Cesium.Cartesian3();
v = new Vector3();

norm = new Vector3();
norm2 = new Vector3();
cnorm = new Cesium.Cartesian3();
cnorm2 = new Cesium.Cartesian3();

c_unitEllipse = new Cesium.Ellipsoid( 1, 1, 1 );
unitEllipse = new Ellipsoid( 1, 1, 1 );
Expand Down
1 change: 1 addition & 0 deletions test/PriorityQueue.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { PriorityQueue } from '../src/utilities/PriorityQueue.js';

// eslint-disable-next-line
globalThis.requestAnimationFrame = cb => setTimeout( cb );
const nextFrame = () => new Promise( resolve => requestAnimationFrame( resolve ) );

Expand Down

0 comments on commit c8eb6a8

Please sign in to comment.