@openglobus/og 0.16.3 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/css/og.css +24 -2
- package/dist/@openglobus/og.css +1 -1
- package/dist/@openglobus/og.esm.js +2 -2
- package/dist/@openglobus/og.esm.js.map +1 -1
- package/dist/@openglobus/og.umd.js +2 -2
- package/dist/@openglobus/og.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/og/Clock.js +1 -5
- package/src/og/Events.js +0 -4
- package/src/og/Extent.js +5 -9
- package/src/og/Globe.js +92 -55
- package/src/og/ImageCanvas.js +12 -5
- package/src/og/Lock.js +44 -48
- package/src/og/LonLat.js +0 -4
- package/src/og/Object3d.js +1 -1
- package/src/og/Stack.js +49 -53
- package/src/og/astro/earth.js +112 -116
- package/src/og/astro/jd.js +514 -518
- package/src/og/astro/orbit.js +119 -123
- package/src/og/astro/rotation.js +36 -40
- package/src/og/bv/Box.js +77 -81
- package/src/og/bv/Sphere.js +57 -61
- package/src/og/camera/Camera.js +20 -7
- package/src/og/camera/PlanetCamera.js +8 -15
- package/src/og/control/Atmosphere.js +0 -4
- package/src/og/control/Control.js +9 -8
- package/src/og/control/DebugInfo.js +0 -4
- package/src/og/control/DrawingSwitcher.js +117 -0
- package/src/og/control/EarthCoordinates.js +214 -214
- package/src/og/control/GeoImageDragControl.js +0 -4
- package/src/og/control/KeyboardNavigation.js +0 -4
- package/src/og/control/LayerAnimation.js +0 -4
- package/src/og/control/LayerSwitcher.js +2 -4
- package/src/og/control/Lighting.js +11 -15
- package/src/og/control/MouseNavigation.js +0 -4
- package/src/og/control/MouseWheelZoomControl.js +0 -4
- package/src/og/control/RulerSwitcher.js +0 -4
- package/src/og/control/ScaleControl.js +2 -6
- package/src/og/control/ShowFps.js +40 -44
- package/src/og/control/SimpleNavigation.js +10 -10
- package/src/og/control/SimpleSkyBackground.js +0 -4
- package/src/og/control/Sun.js +0 -4
- package/src/og/control/ToggleWireframe.js +35 -39
- package/src/og/control/ZoomControl.js +0 -4
- package/src/og/control/drawing/DrawingControl.js +51 -0
- package/src/og/control/drawing/LineStringDrawingScene.js +203 -0
- package/src/og/control/drawing/PolygonDrawingScene.js +785 -0
- package/src/og/control/elevationProfile/ElevationProfile.js +275 -0
- package/src/og/control/index.js +5 -1
- package/src/og/control/ruler/Ruler.js +0 -4
- package/src/og/control/ruler/RulerScene.js +3 -2
- package/src/og/control/selection/Selection.js +0 -4
- package/src/og/control/selection/SelectionScene.js +2 -4
- package/src/og/control/timeline/TimelineControl.js +4 -4
- package/src/og/control/timeline/TimelineModel.js +2 -2
- package/src/og/control/timeline/TimelineView.js +1 -0
- package/src/og/control/visibleExtent/Segment.js +5 -5
- package/src/og/control/visibleExtent/drawnode.js +0 -4
- package/src/og/ellipsoid/Ellipsoid.js +205 -275
- package/src/og/ellipsoid/wgs84.js +0 -4
- package/src/og/entity/BaseBillboard.js +375 -379
- package/src/og/entity/Billboard.js +0 -4
- package/src/og/entity/BillboardHandler.js +0 -4
- package/src/og/entity/Entity.js +22 -22
- package/src/og/entity/EntityCollection.js +7 -11
- package/src/og/entity/GeoObject.js +0 -4
- package/src/og/entity/GeoObjectHandler.js +0 -4
- package/src/og/entity/Geometry.js +5 -4
- package/src/og/entity/GeometryHandler.js +3 -4
- package/src/og/entity/Label.js +0 -4
- package/src/og/entity/LabelHandler.js +0 -4
- package/src/og/entity/PointCloud.js +0 -4
- package/src/og/entity/PointCloudHandler.js +122 -126
- package/src/og/entity/Polyline.js +4 -6
- package/src/og/entity/PolylineHandler.js +104 -108
- package/src/og/entity/Ray.js +29 -29
- package/src/og/entity/Strip.js +1 -1
- package/src/og/index.js +3 -1
- package/src/og/input/KeyboardHandler.js +128 -132
- package/src/og/input/MouseHandler.js +94 -98
- package/src/og/input/TouchHandler.js +59 -63
- package/src/og/input/input.js +44 -48
- package/src/og/layer/BaseGeoImage.js +5 -8
- package/src/og/layer/CanvasTiles.js +0 -4
- package/src/og/layer/GeoImage.js +0 -4
- package/src/og/layer/GeoTexture2d.js +0 -4
- package/src/og/layer/GeoVideo.js +0 -4
- package/src/og/layer/KML.js +1 -0
- package/src/og/layer/Layer.js +22 -26
- package/src/og/layer/Material.js +0 -4
- package/src/og/layer/Vector.js +23 -20
- package/src/og/layer/WMS.js +182 -186
- package/src/og/layer/XYZ.js +0 -4
- package/src/og/light/LightSource.js +0 -4
- package/src/og/math/Line2.js +28 -32
- package/src/og/math/Mat3.js +152 -156
- package/src/og/math/Ray.js +0 -4
- package/src/og/math/Vec2.js +0 -4
- package/src/og/math/Vec3.js +0 -4
- package/src/og/math/Vec4.js +0 -4
- package/src/og/math/coder.js +104 -104
- package/src/og/math.js +39 -7
- package/src/og/proj/EPSG3857.js +13 -13
- package/src/og/proj/Proj.js +59 -63
- package/src/og/quadTree/EPSG4326QuadTreeStrategy.js +1 -0
- package/src/og/quadTree/EarthQuadTreeStrategy.js +1 -0
- package/src/og/quadTree/EntityCollectionNode.js +12 -16
- package/src/og/quadTree/MarsQuadTreeStrategy.js +1 -0
- package/src/og/quadTree/QuadTreeStrategy.js +1 -0
- package/src/og/quadTree/Wgs84QuadTreeStrategy.js +1 -0
- package/src/og/renderer/Renderer.js +109 -22
- package/src/og/renderer/RendererEvents.js +0 -4
- package/src/og/scene/Axes.js +74 -78
- package/src/og/scene/BaseNode.js +0 -4
- package/src/og/scene/Planet.js +114 -112
- package/src/og/scene/RenderNode.js +11 -3
- package/src/og/scene/SkyBox.js +104 -108
- package/src/og/segment/Segment.js +8 -4
- package/src/og/segment/SegmentLonLat.js +2 -6
- package/src/og/segment/segmentHelper.js +229 -225
- package/src/og/shaders/billboard.js +0 -4
- package/src/og/shaders/drawnode.js +5 -9
- package/src/og/shaders/geoObject.js +0 -4
- package/src/og/shaders/label.js +0 -4
- package/src/og/shaders/pickingMask.js +0 -4
- package/src/og/shaders/pointCloud.js +0 -4
- package/src/og/shaders/polyline.js +0 -4
- package/src/og/shaders/ray.js +0 -4
- package/src/og/shaders/skybox.js +0 -4
- package/src/og/terrain/EmptyTerrain.js +0 -4
- package/src/og/utils/FontAtlas.js +0 -4
- package/src/og/utils/GeoImageCreator.js +1 -2
- package/src/og/utils/NormalMapCreator.js +8 -9
- package/src/og/utils/VectorTileCreator.js +3 -9
- package/src/og/utils/shared.js +20 -1
- package/src/og/webgl/Framebuffer.js +0 -4
- package/src/og/webgl/Handler.js +45 -19
- package/src/og/webgl/Multisample.js +0 -4
- package/src/og/webgl/Program.js +0 -4
- package/src/og/webgl/ProgramController.js +2 -2
- package/types/Clock.d.ts +1 -1
- package/types/Extent.d.ts +5 -5
- package/types/Globe.d.ts +15 -1
- package/types/ImageCanvas.d.ts +5 -0
- package/types/bv/Box.d.ts +1 -1
- package/types/bv/Sphere.d.ts +3 -3
- package/types/camera/Camera.d.ts +3 -2
- package/types/camera/PlanetCamera.d.ts +4 -4
- package/types/control/DrawingSwitcher.d.ts +13 -0
- package/types/control/EarthCoordinates.d.ts +1 -1
- package/types/control/Lighting.d.ts +8 -8
- package/types/control/drawing/DrawingControl.d.ts +14 -0
- package/types/control/drawing/LineStringDrawingScene.d.ts +5 -0
- package/types/control/drawing/PolygonDrawingScene.d.ts +99 -0
- package/types/control/index.d.ts +3 -1
- package/types/control/ruler/RulerScene.d.ts +0 -1
- package/types/control/selection/SelectionScene.d.ts +0 -1
- package/types/ellipsoid/Ellipsoid.d.ts +50 -63
- package/types/entity/Entity.d.ts +3 -2
- package/types/entity/Geometry.d.ts +5 -0
- package/types/entity/Polyline.d.ts +1 -1
- package/types/entity/Ray.d.ts +1 -0
- package/types/index.d.ts +1 -0
- package/types/layer/BaseGeoImage.d.ts +1 -1
- package/types/layer/CanvasTiles.d.ts +1 -1
- package/types/layer/Layer.d.ts +1 -1
- package/types/layer/Vector.d.ts +1 -0
- package/types/math.d.ts +7 -0
- package/types/renderer/Renderer.d.ts +7 -1
- package/types/scene/Axes.d.ts +0 -1
- package/types/scene/Planet.d.ts +26 -24
- package/types/scene/RenderNode.d.ts +2 -0
- package/types/scene/SkyBox.d.ts +0 -1
- package/types/segment/Segment.d.ts +3 -2
- package/types/segment/SegmentLonLat.d.ts +0 -1
- package/types/utils/GeoImageCreator.d.ts +1 -1
- package/types/utils/NormalMapCreator.d.ts +1 -1
- package/types/utils/VectorTileCreator.d.ts +2 -2
- package/types/utils/shared.d.ts +2 -0
- package/types/webgl/Handler.d.ts +6 -4
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module og/ellipsoid/Ellipsoid
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
1
|
"use strict";
|
|
6
2
|
|
|
7
3
|
import { LonLat } from "../LonLat.js";
|
|
@@ -43,34 +39,8 @@ class Ellipsoid {
|
|
|
43
39
|
this._invRadii2 = new Vec3(1.0 / this._a2, 1.0 / this._b2, 1.0 / this._a2);
|
|
44
40
|
}
|
|
45
41
|
|
|
46
|
-
/**
|
|
47
|
-
* Returns angle between to bearin angles
|
|
48
|
-
* @param {number} a - First bearing angle
|
|
49
|
-
* @param {number} b - Second bearing angle
|
|
50
|
-
* @returns {number}
|
|
51
|
-
*/
|
|
52
|
-
static getAngleBetweenTwoBearings(a, b) {
|
|
53
|
-
a = zeroTwoPI(a);
|
|
54
|
-
b = zeroTwoPI(b);
|
|
55
|
-
return ((((a - b) % 360) + 360 + 180) % 360) - 180;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
static getRelativeBearing(a, b) {
|
|
59
|
-
let a_y = Math.cos(a),
|
|
60
|
-
a_x = Math.sin(a),
|
|
61
|
-
b_y = Math.cos(b),
|
|
62
|
-
b_x = Math.sin(b);
|
|
63
|
-
let c = a_y * b_x - b_y * a_x,
|
|
64
|
-
d = a_x * b_x + a_y * b_y;
|
|
65
|
-
if (c > 0.0) {
|
|
66
|
-
return Math.acos(d);
|
|
67
|
-
}
|
|
68
|
-
return -Math.acos(d);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
42
|
/**
|
|
72
43
|
* Returns the distance travelling from ‘this’ point to destination point along a rhumb line.
|
|
73
|
-
*
|
|
74
44
|
* @param {LonLat} start coordinates.
|
|
75
45
|
* @param {LonLat} end coordinates
|
|
76
46
|
* @returns {number} Distance in m between this point and destination point (same units as radius).
|
|
@@ -87,30 +57,6 @@ class Ellipsoid {
|
|
|
87
57
|
return t * this._a;
|
|
88
58
|
}
|
|
89
59
|
|
|
90
|
-
/**
|
|
91
|
-
* Returns the midpoint between two points on the great circle.
|
|
92
|
-
* @param {LonLat} lonLat1 - Longitude/latitude of first point.
|
|
93
|
-
* @param {LonLat} lonLat2 - Longitude/latitude of second point.
|
|
94
|
-
* @return {LonLat} Midpoint between points.
|
|
95
|
-
*/
|
|
96
|
-
static getMiddlePointOnGreatCircle(lonLat1, lonLat2) {
|
|
97
|
-
var f1 = lonLat1.lat * RADIANS,
|
|
98
|
-
l1 = lonLat1.lon * RADIANS;
|
|
99
|
-
var f2 = lonLat2.lat * RADIANS;
|
|
100
|
-
var dl = (lonLat2.lon - lonLat1.lon) * RADIANS;
|
|
101
|
-
|
|
102
|
-
var Bx = Math.cos(f2) * Math.cos(dl);
|
|
103
|
-
var By = Math.cos(f2) * Math.sin(dl);
|
|
104
|
-
|
|
105
|
-
var x = Math.sqrt((Math.cos(f1) + Bx) * (Math.cos(f1) + Bx) + By * By);
|
|
106
|
-
var y = Math.sin(f1) + Math.sin(f2);
|
|
107
|
-
var f3 = Math.atan2(y, x);
|
|
108
|
-
|
|
109
|
-
var l3 = l1 + Math.atan2(By, Math.cos(f1) + Bx);
|
|
110
|
-
|
|
111
|
-
return new LonLat(((l3 * DEGREES + 540) % 360) - 180, f3 * DEGREES);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
60
|
/**
|
|
115
61
|
* Returns the point at given fraction between two points on the great circle.
|
|
116
62
|
* @param {LonLat} lonLat1 - Longitude/Latitude of source point.
|
|
@@ -118,57 +64,23 @@ class Ellipsoid {
|
|
|
118
64
|
* @param {number} fraction - Fraction between the two points (0 = source point, 1 = destination point).
|
|
119
65
|
* @returns {LonLat} Intermediate point between points.
|
|
120
66
|
*/
|
|
121
|
-
|
|
122
|
-
var f1 = lonLat1.lat * RADIANS,
|
|
123
|
-
l1 = lonLat1.lon * RADIANS;
|
|
124
|
-
var f2 = lonLat2.lat * RADIANS,
|
|
125
|
-
l2 = lonLat2.lon * RADIANS;
|
|
67
|
+
getIntermediatePointOnGreatCircle(lonLat1, lonLat2, fraction) {
|
|
126
68
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
sinl1 = Math.sin(l1),
|
|
130
|
-
cosl1 = Math.cos(l1);
|
|
131
|
-
var sinf2 = Math.sin(f2),
|
|
132
|
-
cosf2 = Math.cos(f2),
|
|
133
|
-
sinl2 = Math.sin(l2),
|
|
134
|
-
cosl2 = Math.cos(l2);
|
|
135
|
-
|
|
136
|
-
var df = f2 - f1,
|
|
137
|
-
dl = l2 - l1;
|
|
138
|
-
var a =
|
|
139
|
-
Math.sin(df / 2) * Math.sin(df / 2) +
|
|
140
|
-
Math.cos(f1) * Math.cos(f2) * Math.sin(dl / 2) * Math.sin(dl / 2);
|
|
141
|
-
var d = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
|
69
|
+
if (fraction == 0) return lonLat1.clone();
|
|
70
|
+
if (fraction == 1) return lonLat2.clone();
|
|
142
71
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
var y = A * cosf1 * sinl1 + B * cosf2 * sinl2;
|
|
148
|
-
var z = A * sinf1 + B * sinf2;
|
|
149
|
-
|
|
150
|
-
var f3 = Math.atan2(z, Math.sqrt(x * x + y * y));
|
|
151
|
-
var l3 = Math.atan2(y, x);
|
|
152
|
-
|
|
153
|
-
return new LonLat(((l3 * DEGREES + 540) % 360) - 180, f3 * DEGREES);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
static getRhumbBearing(lonLat1, lonLat2) {
|
|
157
|
-
var dLon = (lonLat2.lon - lonLat1.lon) * RADIANS;
|
|
158
|
-
var dPhi = Math.log(
|
|
159
|
-
Math.tan((lonLat2.lat * RADIANS) / 2 + Math.PI / 4) /
|
|
160
|
-
Math.tan((lonLat1.lat * RADIANS) / 2 + Math.PI / 4)
|
|
161
|
-
);
|
|
162
|
-
if (Math.abs(dLon) > Math.PI) {
|
|
163
|
-
if (dLon > 0) {
|
|
164
|
-
dLon = (2 * Math.PI - dLon) * -1;
|
|
165
|
-
} else {
|
|
166
|
-
dLon = 2 * Math.PI + dLon;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
return (Math.atan2(dLon, dPhi) * DEGREES + 360) % 360;
|
|
72
|
+
const inverse = this.inverse(lonLat1, lonLat2);
|
|
73
|
+
const dist = inverse.distance;
|
|
74
|
+
const azimuth = inverse.initialAzimuth;
|
|
75
|
+
return isNaN(azimuth) ? lonLat1 : this.getGreatCircleDestination(lonLat1, azimuth, dist * fraction);
|
|
170
76
|
}
|
|
171
77
|
|
|
78
|
+
/**
|
|
79
|
+
* REMOVE ASAP after
|
|
80
|
+
* @param lonLat1
|
|
81
|
+
* @param lonLat2
|
|
82
|
+
* @returns {number}
|
|
83
|
+
*/
|
|
172
84
|
static getBearing(lonLat1, lonLat2) {
|
|
173
85
|
var f1 = lonLat1.lat * RADIANS,
|
|
174
86
|
l1 = lonLat1.lon * RADIANS;
|
|
@@ -179,101 +91,8 @@ class Ellipsoid {
|
|
|
179
91
|
return Math.atan2(y, x) * DEGREES;
|
|
180
92
|
}
|
|
181
93
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
* @param {LonLat} lonLat1 - Longitude/latitude of source point.
|
|
185
|
-
* @param {LonLat} lonLat2 - Longitude/latitude of destination point.
|
|
186
|
-
* @return {number} Initial bearing in degrees from north.
|
|
187
|
-
*/
|
|
188
|
-
static getInitialBearing(lonLat1, lonLat2) {
|
|
189
|
-
var f1 = lonLat1.lat * RADIANS,
|
|
190
|
-
f2 = lonLat2.lat * RADIANS;
|
|
191
|
-
var dl = (lonLat2.lon - lonLat1.lon) * RADIANS;
|
|
192
|
-
var y = Math.sin(dl) * Math.cos(f2);
|
|
193
|
-
var x = Math.cos(f1) * Math.sin(f2) - Math.sin(f1) * Math.cos(f2) * Math.cos(dl);
|
|
194
|
-
var D = Math.atan2(y, x);
|
|
195
|
-
return (D * DEGREES + 360) % 360;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Returns the point of intersection of two paths defined by point and bearing.
|
|
200
|
-
* @param {LonLat} p1 - First point.
|
|
201
|
-
* @param {number} brng1 - Initial bearing from first point.
|
|
202
|
-
* @param {LonLat} p2 - Second point.
|
|
203
|
-
* @param {number} brng2 - Initial bearing from second point.
|
|
204
|
-
* @return {LonLat|null} Destination point (null if no unique intersection defined).
|
|
205
|
-
*/
|
|
206
|
-
static intersection(p1, brng1, p2, brng2) {
|
|
207
|
-
var f1 = p1.lat * RADIANS,
|
|
208
|
-
l1 = p1.lon * RADIANS;
|
|
209
|
-
var f2 = p2.lat * RADIANS,
|
|
210
|
-
l2 = p2.lon * RADIANS;
|
|
211
|
-
var D13 = brng1 * RADIANS,
|
|
212
|
-
D23 = brng2 * RADIANS;
|
|
213
|
-
var df = f2 - f1,
|
|
214
|
-
dl = l2 - l1;
|
|
215
|
-
|
|
216
|
-
var d12 =
|
|
217
|
-
2 *
|
|
218
|
-
Math.asin(
|
|
219
|
-
Math.sqrt(
|
|
220
|
-
Math.sin(df / 2) * Math.sin(df / 2) +
|
|
221
|
-
Math.cos(f1) * Math.cos(f2) * Math.sin(dl / 2) * Math.sin(dl / 2)
|
|
222
|
-
)
|
|
223
|
-
);
|
|
224
|
-
if (d12 == 0) return null;
|
|
225
|
-
|
|
226
|
-
// initial/final bearings between points
|
|
227
|
-
var Da = Math.acos(
|
|
228
|
-
(Math.sin(f2) - Math.sin(f1) * Math.cos(d12)) / (Math.sin(d12) * Math.cos(f1))
|
|
229
|
-
);
|
|
230
|
-
if (isNaN(Da)) Da = 0; // protect against rounding
|
|
231
|
-
var Db = Math.acos(
|
|
232
|
-
(Math.sin(f1) - Math.sin(f2) * Math.cos(d12)) / (Math.sin(d12) * Math.cos(f2))
|
|
233
|
-
);
|
|
234
|
-
|
|
235
|
-
var D12 = Math.sin(l2 - l1) > 0 ? Da : 2 * Math.PI - Da;
|
|
236
|
-
var D21 = Math.sin(l2 - l1) > 0 ? 2 * Math.PI - Db : Db;
|
|
237
|
-
|
|
238
|
-
var a1 = ((D13 - D12 + Math.PI) % (2 * Math.PI)) - Math.PI;
|
|
239
|
-
var a2 = ((D21 - D23 + Math.PI) % (2 * Math.PI)) - Math.PI;
|
|
240
|
-
|
|
241
|
-
if (Math.sin(a1) == 0 && Math.sin(a2) == 0) return null; // infinite intersections
|
|
242
|
-
if (Math.sin(a1) * Math.sin(a2) < 0) return null; // ambiguous intersection
|
|
243
|
-
|
|
244
|
-
// a1 = Math.abs(a1);
|
|
245
|
-
// a2 = Math.abs(a2);
|
|
246
|
-
// ... Ed Williams takes abs of a1/a2, but seems to break calculation?
|
|
247
|
-
|
|
248
|
-
var a3 = Math.acos(
|
|
249
|
-
-Math.cos(a1) * Math.cos(a2) + Math.sin(a1) * Math.sin(a2) * Math.cos(d12)
|
|
250
|
-
);
|
|
251
|
-
var d13 = Math.atan2(
|
|
252
|
-
Math.sin(d12) * Math.sin(a1) * Math.sin(a2),
|
|
253
|
-
Math.cos(a2) + Math.cos(a1) * Math.cos(a3)
|
|
254
|
-
);
|
|
255
|
-
var f3 = Math.asin(
|
|
256
|
-
Math.sin(f1) * Math.cos(d13) + Math.cos(f1) * Math.sin(d13) * Math.cos(D13)
|
|
257
|
-
);
|
|
258
|
-
var dl13 = Math.atan2(
|
|
259
|
-
Math.sin(D13) * Math.sin(d13) * Math.cos(f1),
|
|
260
|
-
Math.cos(d13) - Math.sin(f1) * Math.sin(f3)
|
|
261
|
-
);
|
|
262
|
-
var l3 = l1 + dl13;
|
|
263
|
-
|
|
264
|
-
return new LonLat(((l3 * DEGREES + 540) % 360) - 180, f3 * DEGREES);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* Returns final bearing arriving at destination destination point from lonLat1 point; the final bearing
|
|
269
|
-
* will differ from the initial bearing by varying degrees according to distance and latitude.
|
|
270
|
-
* @param {LonLat} lonLat1 - Longitude/latitude of source point.
|
|
271
|
-
* @param {LonLat} lonLat2 - Longitude/latitude of destination point.
|
|
272
|
-
* @return {number} Final bearing in degrees from north.
|
|
273
|
-
*/
|
|
274
|
-
static getFinalBearing(lonLat1, lonLat2) {
|
|
275
|
-
// get initial bearing from destination lonLat2 to lonLat1 & reverse it by adding 180°
|
|
276
|
-
return (Ellipsoid.getInitialBearing(lonLat2, lonLat1) + 180) % 360;
|
|
94
|
+
getFlattening() {
|
|
95
|
+
return this._flattening;
|
|
277
96
|
}
|
|
278
97
|
|
|
279
98
|
/**
|
|
@@ -295,9 +114,9 @@ class Ellipsoid {
|
|
|
295
114
|
}
|
|
296
115
|
|
|
297
116
|
/**
|
|
298
|
-
*
|
|
117
|
+
* Calculate cartesian coordinates by its ECEF geodetic coordinates.
|
|
299
118
|
* @public
|
|
300
|
-
* @param {LonLat} lonlat -
|
|
119
|
+
* @param {LonLat} lonlat - Geodetic coordinates.
|
|
301
120
|
* @returns {Vec3} -
|
|
302
121
|
*/
|
|
303
122
|
lonLatToCartesian(lonlat) {
|
|
@@ -317,10 +136,10 @@ class Ellipsoid {
|
|
|
317
136
|
}
|
|
318
137
|
|
|
319
138
|
/**
|
|
320
|
-
*
|
|
139
|
+
* Calculate cartesian coordinates by its ECEF geodetic coordinates.
|
|
321
140
|
* @public
|
|
322
|
-
* @param {LonLat} lonlat -
|
|
323
|
-
* @param {Vec3} res - Output
|
|
141
|
+
* @param {LonLat} lonlat - Geodetic coordinates.
|
|
142
|
+
* @param {Vec3} res - Output variable reference.
|
|
324
143
|
* @returns {Vec3} -
|
|
325
144
|
*/
|
|
326
145
|
lonLatToCartesianRes(lonlat, res) {
|
|
@@ -375,6 +194,8 @@ class Ellipsoid {
|
|
|
375
194
|
pY = p.y || 0.0,
|
|
376
195
|
pZ = p.z || 0.0;
|
|
377
196
|
|
|
197
|
+
let length = Math.sqrt(pX * pX + pY * pY + pZ * pZ);
|
|
198
|
+
|
|
378
199
|
let invRadii2X = this._invRadii2.x,
|
|
379
200
|
invRadii2Y = this._invRadii2.y,
|
|
380
201
|
invRadii2Z = this._invRadii2.z;
|
|
@@ -391,9 +212,9 @@ class Ellipsoid {
|
|
|
391
212
|
return !Number.isFinite(ratio) ? new Vec3() : first
|
|
392
213
|
}
|
|
393
214
|
|
|
394
|
-
let lambda = ((1.0 - ratio) *
|
|
215
|
+
let lambda = ((1.0 - ratio) * length) / first.mulA(this._invRadii2).length();
|
|
395
216
|
|
|
396
|
-
let m_X, m_Y, m_Z;
|
|
217
|
+
let m_X = 0.0, m_Y = 0.0, m_Z = 0.0;
|
|
397
218
|
|
|
398
219
|
do {
|
|
399
220
|
m_X = 1.0 / (1.0 + lambda * invRadii2X);
|
|
@@ -468,65 +289,96 @@ class Ellipsoid {
|
|
|
468
289
|
return new Vec3(nx * l, ny * l, nz * l);
|
|
469
290
|
}
|
|
470
291
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
* @param {LonLat} lonLat1
|
|
474
|
-
* @param {number} [bearing]
|
|
475
|
-
* @param {number} [distance]
|
|
476
|
-
* @return {LonLat} -
|
|
477
|
-
*/
|
|
478
|
-
getBearingDestination(lonLat1, bearing = 0.0, distance = 0) {
|
|
479
|
-
bearing = bearing * RADIANS;
|
|
480
|
-
var nlon = ((lonLat1.lon + 540) % 360) - 180;
|
|
481
|
-
var f1 = lonLat1.lat * RADIANS,
|
|
482
|
-
l1 = nlon * RADIANS;
|
|
483
|
-
var dR = distance / this._a;
|
|
484
|
-
var f2 = Math.asin(
|
|
485
|
-
Math.sin(f1) * Math.cos(dR) + Math.cos(f1) * Math.sin(dR) * Math.cos(bearing)
|
|
486
|
-
);
|
|
487
|
-
return new LonLat(
|
|
488
|
-
(l1 +
|
|
489
|
-
Math.atan2(
|
|
490
|
-
Math.sin(bearing) * Math.sin(dR) * Math.cos(f1),
|
|
491
|
-
Math.cos(dR) - Math.sin(f1) * Math.sin(f2)
|
|
492
|
-
)) *
|
|
493
|
-
DEGREES,
|
|
494
|
-
f2 * DEGREES
|
|
495
|
-
);
|
|
292
|
+
getGreatCircleDistance(lonLat1, lonLat2) {
|
|
293
|
+
return this.inverse(lonLat1, lonLat2).distance;
|
|
496
294
|
}
|
|
497
295
|
|
|
498
296
|
/**
|
|
499
|
-
*
|
|
500
|
-
*
|
|
501
|
-
*
|
|
502
|
-
* @
|
|
297
|
+
* Calculates the destination point given start point lat / lon, azimuth(deg) and distance (m).
|
|
298
|
+
* Source: http://movable-type.co.uk/scripts/latlong-vincenty-direct.html and optimized / cleaned up by Mathias Bynens <http://mathiasbynens.be/>
|
|
299
|
+
* Based on the Vincenty direct formula by T. Vincenty, “Direct and Inverse Solutions of Geodesics on the Ellipsoid with application of nested equations”, Survey Review, vol XXII no 176, 1975 <http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf>
|
|
300
|
+
* @param {LonLat} lonLat - Origin coordinates
|
|
301
|
+
* @param {number} azimuth - View azimuth in degrees
|
|
302
|
+
* @param {number} dist - Distance to the destination point coordinates in meters
|
|
303
|
+
* @returns {LonLat} - Destination point coordinates
|
|
503
304
|
*/
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
305
|
+
getGreatCircleDestination(lonLat, azimuth, dist) {
|
|
306
|
+
return this.direct(lonLat, azimuth, dist).destination;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
inverse(lonLat1, lonLat2) {
|
|
310
|
+
|
|
311
|
+
let a = this._a, b = this._b, f = this._flattening;
|
|
312
|
+
|
|
313
|
+
const fi1 = lonLat1.lat * RADIANS, lambda1 = lonLat1.lon * RADIANS;
|
|
314
|
+
const fi2 = lonLat2.lat * RADIANS, lambda2 = lonLat2.lon * RADIANS;
|
|
315
|
+
|
|
316
|
+
const L = lambda2 - lambda1; // L = difference in longitude, U = reduced latitude, defined by tan U = (1-f)·tanφ.
|
|
317
|
+
const tanU1 = (1 - f) * Math.tan(fi1), cosU1 = 1 / Math.sqrt((1 + tanU1 * tanU1)), sinU1 = tanU1 * cosU1;
|
|
318
|
+
const tanU2 = (1 - f) * Math.tan(fi2), cosU2 = 1 / Math.sqrt((1 + tanU2 * tanU2)), sinU2 = tanU2 * cosU2;
|
|
319
|
+
|
|
320
|
+
const antipodal = Math.abs(L) > Math.PI / 2 || Math.abs(fi2 - fi1) > Math.PI / 2;
|
|
321
|
+
|
|
322
|
+
let lmb = L, sinLmb = null, cosLmb = null; // lmb - difference in longitude on an auxiliary sphere
|
|
323
|
+
let s = antipodal ? Math.PI : 0, sin_s = 0, cos_s = antipodal ? -1 : 1, sinSqs = null; // s - angular distance lonLat1 lonLat2 on the sphere
|
|
324
|
+
let cos2sm = 1; // sm - angular distance on the sphere from the equator to the midpoint of the line
|
|
325
|
+
let cosSqa = 1; // a - azimuth of the geodesic at the equator
|
|
326
|
+
|
|
327
|
+
let lmb_ = null, iterations = 0;
|
|
328
|
+
do {
|
|
329
|
+
sinLmb = Math.sin(lmb);
|
|
330
|
+
cosLmb = Math.cos(lmb);
|
|
331
|
+
sinSqs = (cosU2 * sinLmb) ** 2 + (cosU1 * sinU2 - sinU1 * cosU2 * cosLmb) ** 2;
|
|
332
|
+
if (Math.abs(sinSqs) < 1e-24) break; // co-incident/antipodal points (σ < ≈0.006mm)
|
|
333
|
+
sin_s = Math.sqrt(sinSqs);
|
|
334
|
+
cos_s = sinU1 * sinU2 + cosU1 * cosU2 * cosLmb;
|
|
335
|
+
s = Math.atan2(sin_s, cos_s);
|
|
336
|
+
const sin_a = cosU1 * cosU2 * sinLmb / sin_s;
|
|
337
|
+
cosSqa = 1 - sin_a * sin_a;
|
|
338
|
+
cos2sm = (cosSqa != 0) ? (cos_s - 2 * sinU1 * sinU2 / cosSqa) : 0; // on equatorial line cos²α = 0 (§6)
|
|
339
|
+
const C = f / 16 * cosSqa * (4 + f * (4 - 3 * cosSqa));
|
|
340
|
+
lmb_ = lmb;
|
|
341
|
+
lmb = L + (1 - C) * f * sin_a * (s + C * sin_s * (cos2sm + C * cos_s * (-1 + 2 * cos2sm * cos2sm)));
|
|
342
|
+
} while (Math.abs(lmb - lmb_) > EPS12 && ++iterations < 1000);
|
|
343
|
+
|
|
344
|
+
const uSq = cosSqa * (a * a - b * b) / (b * b);
|
|
345
|
+
const A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
|
|
346
|
+
const B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
|
|
347
|
+
const ds = B * sin_s * (cos2sm + B / 4 * (cos_s * (-1 + 2 * cos2sm * cos2sm) - B / 6 * cos2sm * (-3 + 4 * sin_s * sin_s) * (-3 + 4 * cos2sm * cos2sm)));
|
|
348
|
+
|
|
349
|
+
const dist = b * A * (s - ds); // s = length of the geodesic
|
|
350
|
+
|
|
351
|
+
// note special handling of exactly antipodal points where sin²σ = 0 (due to discontinuity
|
|
352
|
+
// atan2(0, 0) = 0 but atan2(ε, 0) = π/2 / 90°) - in which case bearing is always meridional,
|
|
353
|
+
// due north (or due south!)
|
|
354
|
+
// α = azimuths of the geodesic; α2 the direction P₁ P₂ produced
|
|
355
|
+
const a1 = Math.abs(sinSqs) < Number.EPSILON ? 0 : Math.atan2(cosU2 * sinLmb, cosU1 * sinU2 - sinU1 * cosU2 * cosLmb);
|
|
356
|
+
const a2 = Math.abs(sinSqs) < Number.EPSILON ? Math.PI : Math.atan2(cosU1 * sinLmb, -sinU1 * cosU2 + cosU1 * sinU2 * cosLmb);
|
|
357
|
+
|
|
358
|
+
return {
|
|
359
|
+
distance: dist,
|
|
360
|
+
initialAzimuth: Math.abs(dist) < Number.EPSILON ? NaN : zeroTwoPI(a1) * DEGREES,
|
|
361
|
+
finalAzimuth: Math.abs(dist) < Number.EPSILON ? NaN : zeroTwoPI(a2) * DEGREES
|
|
362
|
+
};
|
|
514
363
|
}
|
|
515
364
|
|
|
516
365
|
/**
|
|
517
|
-
* Calculates the destination point given start point lat / lon,
|
|
518
|
-
*
|
|
519
|
-
* Taken from http://movable-type.co.uk/scripts/latlong-vincenty-direct.html and optimized / cleaned up by Mathias Bynens <http://mathiasbynens.be/>
|
|
366
|
+
* Calculates the destination point given start point lat / lon, azimuth(deg) and distance (m).
|
|
367
|
+
* Source: http://movable-type.co.uk/scripts/latlong-vincenty-direct.html and optimized / cleaned up by Mathias Bynens <http://mathiasbynens.be/>
|
|
520
368
|
* Based on the Vincenty direct formula by T. Vincenty, “Direct and Inverse Solutions of Geodesics on the Ellipsoid with application of nested equations”, Survey Review, vol XXII no 176, 1975 <http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf>
|
|
369
|
+
* @param {LonLat} lonLat - Origin coordinates
|
|
370
|
+
* @param {number} azimuth - View azimuth in degrees
|
|
371
|
+
* @param {number} dist - Distance to the destination point coordinates in meters
|
|
372
|
+
* @returns {LonLat} - Destination point coordinates
|
|
521
373
|
*/
|
|
522
|
-
|
|
523
|
-
|
|
374
|
+
direct(lonLat, azimuth, dist) {
|
|
375
|
+
let lon1 = lonLat.lon,
|
|
524
376
|
lat1 = lonLat.lat;
|
|
525
|
-
|
|
377
|
+
let a = this._a,
|
|
526
378
|
b = this._b,
|
|
527
|
-
f =
|
|
379
|
+
f = this._flattening,
|
|
528
380
|
s = dist,
|
|
529
|
-
alpha1 =
|
|
381
|
+
alpha1 = azimuth * RADIANS,
|
|
530
382
|
sinAlpha1 = Math.sin(alpha1),
|
|
531
383
|
cosAlpha1 = Math.cos(alpha1),
|
|
532
384
|
tanU1 = (1 - f) * Math.tan(lat1 * RADIANS),
|
|
@@ -544,20 +396,16 @@ class Ellipsoid {
|
|
|
544
396
|
var cos2SigmaM = Math.cos(2 * sigma1 + sigma),
|
|
545
397
|
sinSigma = Math.sin(sigma),
|
|
546
398
|
cosSigma = Math.cos(sigma),
|
|
547
|
-
deltaSigma =
|
|
548
|
-
B *
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
(B / 6) *
|
|
554
|
-
cos2SigmaM *
|
|
555
|
-
(-3 + 4 * sinSigma * sinSigma) *
|
|
556
|
-
(-3 + 4 * cos2SigmaM * cos2SigmaM)));
|
|
399
|
+
deltaSigma = B * sinSigma *
|
|
400
|
+
(cos2SigmaM + (B / 4) *
|
|
401
|
+
(
|
|
402
|
+
cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) -
|
|
403
|
+
(B / 6) * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM)
|
|
404
|
+
));
|
|
557
405
|
sigmaP = sigma;
|
|
558
406
|
sigma = s / (b * A) + deltaSigma;
|
|
559
407
|
}
|
|
560
|
-
|
|
408
|
+
let tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1,
|
|
561
409
|
lat2 = Math.atan2(
|
|
562
410
|
sinU1 * cosSigma + cosU1 * sinSigma * cosAlpha1,
|
|
563
411
|
(1 - f) * Math.sqrt(sinAlpha * sinAlpha + tmp * tmp)
|
|
@@ -566,22 +414,19 @@ class Ellipsoid {
|
|
|
566
414
|
sinSigma * sinAlpha1,
|
|
567
415
|
cosU1 * cosSigma - sinU1 * sinSigma * cosAlpha1
|
|
568
416
|
),
|
|
569
|
-
C = (f / 16) * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha)),
|
|
570
|
-
L =
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
sinSigma *
|
|
578
|
-
(cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM))),
|
|
579
|
-
revAz = Math.atan2(sinAlpha, -tmp); // final bearing
|
|
580
|
-
return new LonLat(lon1 + L * DEGREES, lat2 * DEGREES);
|
|
417
|
+
C = (f / 16.0) * cosSqAlpha * (4.0 + f * (4.0 - 3.0 * cosSqAlpha)),
|
|
418
|
+
L = lambda - (1.0 - C) * f * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1.0 + 2.0 * cos2SigmaM * cos2SigmaM))),
|
|
419
|
+
revAz = Math.atan2(sinAlpha, -tmp);
|
|
420
|
+
|
|
421
|
+
return {
|
|
422
|
+
destination: new LonLat(lon1 + L * DEGREES, lat2 * DEGREES),
|
|
423
|
+
finalAzimuth: revAz * DEGREES
|
|
424
|
+
};
|
|
581
425
|
}
|
|
582
426
|
|
|
427
|
+
|
|
583
428
|
/**
|
|
584
|
-
* Returns ray
|
|
429
|
+
* Returns cartesian coordinates of the intersection of a ray and an ellipsoid.
|
|
585
430
|
* If the ray doesn't hit ellipsoid returns null.
|
|
586
431
|
* @public
|
|
587
432
|
* @param {Vec3} origin - Ray origin point.
|
|
@@ -646,8 +491,93 @@ class Ellipsoid {
|
|
|
646
491
|
return origin.add(direction.scaleTo(-qw / w2));
|
|
647
492
|
}
|
|
648
493
|
// qw >= 0.0. Looking outward or tangent.
|
|
649
|
-
return
|
|
494
|
+
// return undefined
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* @todo this is not precise function, needs to be replaced or removed
|
|
500
|
+
* @param lonLat1
|
|
501
|
+
* @param bearing
|
|
502
|
+
* @param distance
|
|
503
|
+
* @returns {LonLat}
|
|
504
|
+
*/
|
|
505
|
+
getBearingDestination(lonLat1, bearing = 0.0, distance = 0) {
|
|
506
|
+
bearing = bearing * RADIANS;
|
|
507
|
+
var nlon = ((lonLat1.lon + 540) % 360) - 180;
|
|
508
|
+
var f1 = lonLat1.lat * RADIANS,
|
|
509
|
+
l1 = nlon * RADIANS;
|
|
510
|
+
var dR = distance / this._a;
|
|
511
|
+
var f2 = Math.asin(
|
|
512
|
+
Math.sin(f1) * Math.cos(dR) + Math.cos(f1) * Math.sin(dR) * Math.cos(bearing)
|
|
513
|
+
);
|
|
514
|
+
return new LonLat(
|
|
515
|
+
(l1 +
|
|
516
|
+
Math.atan2(
|
|
517
|
+
Math.sin(bearing) * Math.sin(dR) * Math.cos(f1),
|
|
518
|
+
Math.cos(dR) - Math.sin(f1) * Math.sin(f2)
|
|
519
|
+
)) *
|
|
520
|
+
DEGREES,
|
|
521
|
+
f2 * DEGREES
|
|
522
|
+
);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* Returns the point at given fraction between two points on the great circle.
|
|
527
|
+
* @param {LonLat} lonLat1 - Longitude/Latitude of source point.
|
|
528
|
+
* @param {LonLat} lonLat2 - Longitude/Latitude of destination point.
|
|
529
|
+
* @param {number} fraction - Fraction between the two points (0 = source point, 1 = destination point).
|
|
530
|
+
* @returns {LonLat} Intermediate point between points.
|
|
531
|
+
*/
|
|
532
|
+
static getIntermediatePointOnGreatCircle(lonLat1, lonLat2, fraction) {
|
|
533
|
+
var f1 = lonLat1.lat * RADIANS,
|
|
534
|
+
l1 = lonLat1.lon * RADIANS;
|
|
535
|
+
var f2 = lonLat2.lat * RADIANS,
|
|
536
|
+
l2 = lonLat2.lon * RADIANS;
|
|
537
|
+
|
|
538
|
+
var sinf1 = Math.sin(f1),
|
|
539
|
+
cosf1 = Math.cos(f1),
|
|
540
|
+
sinl1 = Math.sin(l1),
|
|
541
|
+
cosl1 = Math.cos(l1);
|
|
542
|
+
var sinf2 = Math.sin(f2),
|
|
543
|
+
cosf2 = Math.cos(f2),
|
|
544
|
+
sinl2 = Math.sin(l2),
|
|
545
|
+
cosl2 = Math.cos(l2);
|
|
546
|
+
|
|
547
|
+
var df = f2 - f1,
|
|
548
|
+
dl = l2 - l1;
|
|
549
|
+
var a =
|
|
550
|
+
Math.sin(df / 2) * Math.sin(df / 2) +
|
|
551
|
+
Math.cos(f1) * Math.cos(f2) * Math.sin(dl / 2) * Math.sin(dl / 2);
|
|
552
|
+
var d = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
|
553
|
+
|
|
554
|
+
var A = Math.sin((1 - fraction) * d) / Math.sin(d);
|
|
555
|
+
var B = Math.sin(fraction * d) / Math.sin(d);
|
|
556
|
+
|
|
557
|
+
var x = A * cosf1 * cosl1 + B * cosf2 * cosl2;
|
|
558
|
+
var y = A * cosf1 * sinl1 + B * cosf2 * sinl2;
|
|
559
|
+
var z = A * sinf1 + B * sinf2;
|
|
560
|
+
|
|
561
|
+
var f3 = Math.atan2(z, Math.sqrt(x * x + y * y));
|
|
562
|
+
var l3 = Math.atan2(y, x);
|
|
563
|
+
|
|
564
|
+
return new LonLat(((l3 * DEGREES + 540) % 360) - 180, f3 * DEGREES);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
static getRhumbBearing(lonLat1, lonLat2) {
|
|
568
|
+
var dLon = (lonLat2.lon - lonLat1.lon) * RADIANS;
|
|
569
|
+
var dPhi = Math.log(
|
|
570
|
+
Math.tan((lonLat2.lat * RADIANS) / 2 + Math.PI / 4) /
|
|
571
|
+
Math.tan((lonLat1.lat * RADIANS) / 2 + Math.PI / 4)
|
|
572
|
+
);
|
|
573
|
+
if (Math.abs(dLon) > Math.PI) {
|
|
574
|
+
if (dLon > 0) {
|
|
575
|
+
dLon = (2 * Math.PI - dLon) * -1;
|
|
576
|
+
} else {
|
|
577
|
+
dLon = 2 * Math.PI + dLon;
|
|
578
|
+
}
|
|
650
579
|
}
|
|
580
|
+
return (Math.atan2(dLon, dPhi) * DEGREES + 360) % 360;
|
|
651
581
|
}
|
|
652
582
|
}
|
|
653
583
|
|