I am using Cesium to create point in a map. The point will be then flyable with a drone.
I have the following problem,
1) The user set a point altitude to 20 meters in a 2D flat map. 2) The point need to be create at the real world location (long/lat) + 20 meters (altitude). 3) The point will be visible on a 3D map, so at the location (long/lat) + 20 meters (altitude).
Exemple:
Now, from what I understand, Cesium altitude is using WSG84, and my server (that I have no control on) is using MSL.
from what I have seen on Internet I require a geoID to compute the calculation between a WSG84 point and MSL.
it is a straightforward procedure to subtract an interpolated geoid height, N, from a GPS ellipsoidal height, h, to obtain an orthometric height or a height above mean sea level (AMSL), H: H = h - N
I found for example this lib.
I have 3 questions about those procedure =>
1) Is everything I say correct ? am I going the right path ? 2) In the app, there is a flight tracking mode where a user can track a drone flying, but the coordinate come from the server in MSL, I get an update every 100ms, with all those additional calculation, will this part be a problem ? 2) Cesium is of course not 100% accurate, and I believe also that whatever geoID I use (for Japan region) will probably not be that accurate too. What average marge of error is to be expected ?
Thank you
I update this post cause I never replied if anyone was interested =>
import { Injectable, NgZone } from '@angular/core';
import { Cartographic } from 'src/app/shared/models/navigation.models';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class AltimeterService {
terrainProvider = new Cesium.createWorldTerrain();
constructor(private ngZone: NgZone) { }
getElevation(pos: Cartographic): Observable<number> {
return new Observable<number>(observer => {
this.ngZone.run(() => {
const promise = Cesium.sampleTerrainMostDetailed(this.terrainProvider, [new Cesium.Cartographic(pos.longitude, pos.latitude, 0)]);
Cesium.when(promise, (updatedPositions) => {
this.ngZone.run(() => {
observer.next(updatedPositions[0].height);
observer.complete();
});
});
});
});
}
getElevations(pos: Array<Cartographic>): Observable<Array<number>> {
return new Observable<Array<number>>(observer => {
this.ngZone.run(() => {
const copy = new Array<Cartographic>();
pos.forEach((p) => copy.push(new Cesium.Cartographic(p.longitude, p.latitude, 0)));
const promise = Cesium.sampleTerrainMostDetailed(this.terrainProvider, copy);
Cesium.when(promise, (updatedPositions) => {
this.ngZone.run(() => {
const elevations = new Array<number>();
updatedPositions.forEach((p) => elevations.push(p.height));
observer.next(elevations);
observer.complete();
});
});
});
});
}
}
This will get the altitude of a point on the map using Cesium World Terrain. this will be WSG84 value of the altitude at point long/lat
I then pass the value to the server in GOLang that use this package to get the geoID altitude for the given long/ lat
// ConvertGPSElevationToMSL convert gps to msl elevation
// use geolocation package by garrettsickles to get the undulation or geoid from lat and lon
func ConvertGPSElevationToMSL(gpsElevation float32, lat, lon float64) float32 {
return gpsElevation - getGeoID(lat, lon) // geoid - gps elevation
}
// ConvertMSLToGPSElevation convert msl to gps elevation
// use geolocation package by garrettsickles to get the undulation or geoid from lat and lon
func ConvertMSLToGPSElevation(msl float32, lat, lon float64) float32 {
return getGeoID(lat, lon) + msl // should be geoID - the msl (mean sea level)
}