@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.
Files changed (181) hide show
  1. package/README.md +1 -1
  2. package/css/og.css +24 -2
  3. package/dist/@openglobus/og.css +1 -1
  4. package/dist/@openglobus/og.esm.js +2 -2
  5. package/dist/@openglobus/og.esm.js.map +1 -1
  6. package/dist/@openglobus/og.umd.js +2 -2
  7. package/dist/@openglobus/og.umd.js.map +1 -1
  8. package/package.json +1 -1
  9. package/src/og/Clock.js +1 -5
  10. package/src/og/Events.js +0 -4
  11. package/src/og/Extent.js +5 -9
  12. package/src/og/Globe.js +92 -55
  13. package/src/og/ImageCanvas.js +12 -5
  14. package/src/og/Lock.js +44 -48
  15. package/src/og/LonLat.js +0 -4
  16. package/src/og/Object3d.js +1 -1
  17. package/src/og/Stack.js +49 -53
  18. package/src/og/astro/earth.js +112 -116
  19. package/src/og/astro/jd.js +514 -518
  20. package/src/og/astro/orbit.js +119 -123
  21. package/src/og/astro/rotation.js +36 -40
  22. package/src/og/bv/Box.js +77 -81
  23. package/src/og/bv/Sphere.js +57 -61
  24. package/src/og/camera/Camera.js +20 -7
  25. package/src/og/camera/PlanetCamera.js +8 -15
  26. package/src/og/control/Atmosphere.js +0 -4
  27. package/src/og/control/Control.js +9 -8
  28. package/src/og/control/DebugInfo.js +0 -4
  29. package/src/og/control/DrawingSwitcher.js +117 -0
  30. package/src/og/control/EarthCoordinates.js +214 -214
  31. package/src/og/control/GeoImageDragControl.js +0 -4
  32. package/src/og/control/KeyboardNavigation.js +0 -4
  33. package/src/og/control/LayerAnimation.js +0 -4
  34. package/src/og/control/LayerSwitcher.js +2 -4
  35. package/src/og/control/Lighting.js +11 -15
  36. package/src/og/control/MouseNavigation.js +0 -4
  37. package/src/og/control/MouseWheelZoomControl.js +0 -4
  38. package/src/og/control/RulerSwitcher.js +0 -4
  39. package/src/og/control/ScaleControl.js +2 -6
  40. package/src/og/control/ShowFps.js +40 -44
  41. package/src/og/control/SimpleNavigation.js +10 -10
  42. package/src/og/control/SimpleSkyBackground.js +0 -4
  43. package/src/og/control/Sun.js +0 -4
  44. package/src/og/control/ToggleWireframe.js +35 -39
  45. package/src/og/control/ZoomControl.js +0 -4
  46. package/src/og/control/drawing/DrawingControl.js +51 -0
  47. package/src/og/control/drawing/LineStringDrawingScene.js +203 -0
  48. package/src/og/control/drawing/PolygonDrawingScene.js +785 -0
  49. package/src/og/control/elevationProfile/ElevationProfile.js +275 -0
  50. package/src/og/control/index.js +5 -1
  51. package/src/og/control/ruler/Ruler.js +0 -4
  52. package/src/og/control/ruler/RulerScene.js +3 -2
  53. package/src/og/control/selection/Selection.js +0 -4
  54. package/src/og/control/selection/SelectionScene.js +2 -4
  55. package/src/og/control/timeline/TimelineControl.js +4 -4
  56. package/src/og/control/timeline/TimelineModel.js +2 -2
  57. package/src/og/control/timeline/TimelineView.js +1 -0
  58. package/src/og/control/visibleExtent/Segment.js +5 -5
  59. package/src/og/control/visibleExtent/drawnode.js +0 -4
  60. package/src/og/ellipsoid/Ellipsoid.js +205 -275
  61. package/src/og/ellipsoid/wgs84.js +0 -4
  62. package/src/og/entity/BaseBillboard.js +375 -379
  63. package/src/og/entity/Billboard.js +0 -4
  64. package/src/og/entity/BillboardHandler.js +0 -4
  65. package/src/og/entity/Entity.js +22 -22
  66. package/src/og/entity/EntityCollection.js +7 -11
  67. package/src/og/entity/GeoObject.js +0 -4
  68. package/src/og/entity/GeoObjectHandler.js +0 -4
  69. package/src/og/entity/Geometry.js +5 -4
  70. package/src/og/entity/GeometryHandler.js +3 -4
  71. package/src/og/entity/Label.js +0 -4
  72. package/src/og/entity/LabelHandler.js +0 -4
  73. package/src/og/entity/PointCloud.js +0 -4
  74. package/src/og/entity/PointCloudHandler.js +122 -126
  75. package/src/og/entity/Polyline.js +4 -6
  76. package/src/og/entity/PolylineHandler.js +104 -108
  77. package/src/og/entity/Ray.js +29 -29
  78. package/src/og/entity/Strip.js +1 -1
  79. package/src/og/index.js +3 -1
  80. package/src/og/input/KeyboardHandler.js +128 -132
  81. package/src/og/input/MouseHandler.js +94 -98
  82. package/src/og/input/TouchHandler.js +59 -63
  83. package/src/og/input/input.js +44 -48
  84. package/src/og/layer/BaseGeoImage.js +5 -8
  85. package/src/og/layer/CanvasTiles.js +0 -4
  86. package/src/og/layer/GeoImage.js +0 -4
  87. package/src/og/layer/GeoTexture2d.js +0 -4
  88. package/src/og/layer/GeoVideo.js +0 -4
  89. package/src/og/layer/KML.js +1 -0
  90. package/src/og/layer/Layer.js +22 -26
  91. package/src/og/layer/Material.js +0 -4
  92. package/src/og/layer/Vector.js +23 -20
  93. package/src/og/layer/WMS.js +182 -186
  94. package/src/og/layer/XYZ.js +0 -4
  95. package/src/og/light/LightSource.js +0 -4
  96. package/src/og/math/Line2.js +28 -32
  97. package/src/og/math/Mat3.js +152 -156
  98. package/src/og/math/Ray.js +0 -4
  99. package/src/og/math/Vec2.js +0 -4
  100. package/src/og/math/Vec3.js +0 -4
  101. package/src/og/math/Vec4.js +0 -4
  102. package/src/og/math/coder.js +104 -104
  103. package/src/og/math.js +39 -7
  104. package/src/og/proj/EPSG3857.js +13 -13
  105. package/src/og/proj/Proj.js +59 -63
  106. package/src/og/quadTree/EPSG4326QuadTreeStrategy.js +1 -0
  107. package/src/og/quadTree/EarthQuadTreeStrategy.js +1 -0
  108. package/src/og/quadTree/EntityCollectionNode.js +12 -16
  109. package/src/og/quadTree/MarsQuadTreeStrategy.js +1 -0
  110. package/src/og/quadTree/QuadTreeStrategy.js +1 -0
  111. package/src/og/quadTree/Wgs84QuadTreeStrategy.js +1 -0
  112. package/src/og/renderer/Renderer.js +109 -22
  113. package/src/og/renderer/RendererEvents.js +0 -4
  114. package/src/og/scene/Axes.js +74 -78
  115. package/src/og/scene/BaseNode.js +0 -4
  116. package/src/og/scene/Planet.js +114 -112
  117. package/src/og/scene/RenderNode.js +11 -3
  118. package/src/og/scene/SkyBox.js +104 -108
  119. package/src/og/segment/Segment.js +8 -4
  120. package/src/og/segment/SegmentLonLat.js +2 -6
  121. package/src/og/segment/segmentHelper.js +229 -225
  122. package/src/og/shaders/billboard.js +0 -4
  123. package/src/og/shaders/drawnode.js +5 -9
  124. package/src/og/shaders/geoObject.js +0 -4
  125. package/src/og/shaders/label.js +0 -4
  126. package/src/og/shaders/pickingMask.js +0 -4
  127. package/src/og/shaders/pointCloud.js +0 -4
  128. package/src/og/shaders/polyline.js +0 -4
  129. package/src/og/shaders/ray.js +0 -4
  130. package/src/og/shaders/skybox.js +0 -4
  131. package/src/og/terrain/EmptyTerrain.js +0 -4
  132. package/src/og/utils/FontAtlas.js +0 -4
  133. package/src/og/utils/GeoImageCreator.js +1 -2
  134. package/src/og/utils/NormalMapCreator.js +8 -9
  135. package/src/og/utils/VectorTileCreator.js +3 -9
  136. package/src/og/utils/shared.js +20 -1
  137. package/src/og/webgl/Framebuffer.js +0 -4
  138. package/src/og/webgl/Handler.js +45 -19
  139. package/src/og/webgl/Multisample.js +0 -4
  140. package/src/og/webgl/Program.js +0 -4
  141. package/src/og/webgl/ProgramController.js +2 -2
  142. package/types/Clock.d.ts +1 -1
  143. package/types/Extent.d.ts +5 -5
  144. package/types/Globe.d.ts +15 -1
  145. package/types/ImageCanvas.d.ts +5 -0
  146. package/types/bv/Box.d.ts +1 -1
  147. package/types/bv/Sphere.d.ts +3 -3
  148. package/types/camera/Camera.d.ts +3 -2
  149. package/types/camera/PlanetCamera.d.ts +4 -4
  150. package/types/control/DrawingSwitcher.d.ts +13 -0
  151. package/types/control/EarthCoordinates.d.ts +1 -1
  152. package/types/control/Lighting.d.ts +8 -8
  153. package/types/control/drawing/DrawingControl.d.ts +14 -0
  154. package/types/control/drawing/LineStringDrawingScene.d.ts +5 -0
  155. package/types/control/drawing/PolygonDrawingScene.d.ts +99 -0
  156. package/types/control/index.d.ts +3 -1
  157. package/types/control/ruler/RulerScene.d.ts +0 -1
  158. package/types/control/selection/SelectionScene.d.ts +0 -1
  159. package/types/ellipsoid/Ellipsoid.d.ts +50 -63
  160. package/types/entity/Entity.d.ts +3 -2
  161. package/types/entity/Geometry.d.ts +5 -0
  162. package/types/entity/Polyline.d.ts +1 -1
  163. package/types/entity/Ray.d.ts +1 -0
  164. package/types/index.d.ts +1 -0
  165. package/types/layer/BaseGeoImage.d.ts +1 -1
  166. package/types/layer/CanvasTiles.d.ts +1 -1
  167. package/types/layer/Layer.d.ts +1 -1
  168. package/types/layer/Vector.d.ts +1 -0
  169. package/types/math.d.ts +7 -0
  170. package/types/renderer/Renderer.d.ts +7 -1
  171. package/types/scene/Axes.d.ts +0 -1
  172. package/types/scene/Planet.d.ts +26 -24
  173. package/types/scene/RenderNode.d.ts +2 -0
  174. package/types/scene/SkyBox.d.ts +0 -1
  175. package/types/segment/Segment.d.ts +3 -2
  176. package/types/segment/SegmentLonLat.d.ts +0 -1
  177. package/types/utils/GeoImageCreator.d.ts +1 -1
  178. package/types/utils/NormalMapCreator.d.ts +1 -1
  179. package/types/utils/VectorTileCreator.d.ts +2 -2
  180. package/types/utils/shared.d.ts +2 -0
  181. 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
- static getIntermediatePointOnGreatCircle(lonLat1, lonLat2, fraction) {
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
- var sinf1 = Math.sin(f1),
128
- cosf1 = Math.cos(f1),
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
- var A = Math.sin((1 - fraction) * d) / Math.sin(d);
144
- var B = Math.sin(fraction * d) / Math.sin(d);
145
-
146
- var x = A * cosf1 * cosl1 + B * cosf2 * cosl2;
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
- * Returns the (initial) bearing from source to destination point on the great circle.
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
- * Gets cartesian ECEF from Wgs84 geodetic coordinates.
117
+ * Calculate cartesian coordinates by its ECEF geodetic coordinates.
299
118
  * @public
300
- * @param {LonLat} lonlat - Degrees geodetic coordinates.
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
- * Gets cartesian ECEF from Wgs84 geodetic coordinates.
139
+ * Calculate cartesian coordinates by its ECEF geodetic coordinates.
321
140
  * @public
322
- * @param {LonLat} lonlat - Degrees geodetic coordinates.
323
- * @param {Vec3} res - Output result.
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) * p.length()) / first.mulA(this._invRadii2).length();
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
- * Returns the distance from one point to another(using haversine formula) on the great circle.
500
- * @param {LonLat} lonLat1 - Longitude/latitude of source point.
501
- * @param {LonLat} lonLat2 - Longitude/latitude of destination point.
502
- * @return {number} Distance between points.
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
- getGreatCircleDistance(lonLat1, lonLat2) {
505
- var dLat = (lonLat2.lat - lonLat1.lat) * RADIANS;
506
- var dLon = (lonLat2.lon - lonLat1.lon) * RADIANS;
507
- var a =
508
- Math.sin(dLat / 2.0) * Math.sin(dLat / 2.0) +
509
- Math.sin(dLon / 2.0) *
510
- Math.sin(dLon / 2) *
511
- Math.cos(lonLat1.lat * RADIANS) *
512
- Math.cos(lonLat2.lat * RADIANS);
513
- return this._a * 2.0 * Math.atan2(Math.sqrt(a), Math.sqrt(1.0 - a));
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, bearing(deg) and distance (m).
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
- getGreatCircleDestination(lonLat, brng, dist) {
523
- var lon1 = lonLat.lon,
374
+ direct(lonLat, azimuth, dist) {
375
+ let lon1 = lonLat.lon,
524
376
  lat1 = lonLat.lat;
525
- var a = this._a,
377
+ let a = this._a,
526
378
  b = this._b,
527
- f = 1.0 / this._f,
379
+ f = this._flattening,
528
380
  s = dist,
529
- alpha1 = brng * RADIANS,
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
- sinSigma *
550
- (cos2SigmaM +
551
- (B / 4) *
552
- (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) -
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
- var tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1,
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
- lambda -
572
- (1 - C) *
573
- f *
574
- sinAlpha *
575
- (sigma +
576
- C *
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 vector hit ellipsoid coordinates.
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 null;
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
 
@@ -1,7 +1,3 @@
1
- /**
2
- * @module og/ellipsoid/wgs84
3
- */
4
-
5
1
  "use strict";
6
2
 
7
3
  import { Ellipsoid } from "./Ellipsoid.js";