@pirireis/webglobeplugins 0.17.0 → 1.0.2

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 (274) hide show
  1. package/Math/{angle-calculation.js → angle-calculation.ts} +18 -14
  2. package/Math/{arc-cdf-points.js → arc-cdf-points.ts} +329 -272
  3. package/Math/{arc-generate-points-exponantial.js → arc-generate-points-exponantial.ts} +299 -254
  4. package/Math/{arc.js → arc.ts} +421 -292
  5. package/Math/bounds/line-bbox.js +225 -186
  6. package/Math/{circle-cdf-points.js → circle-cdf-points.ts} +143 -78
  7. package/Math/{circle.js → circle.ts} +49 -33
  8. package/Math/{constants.js → constants.ts} +12 -4
  9. package/Math/contour/{quadtreecontours.js → quadtreecontours.ts} +371 -300
  10. package/Math/contour/quadtreecontours1.js +336 -298
  11. package/Math/{finite-line-2d.js → finite-line-2d.ts} +68 -58
  12. package/Math/haversine.ts +33 -0
  13. package/Math/index.js +0 -1
  14. package/Math/juction/{arc-plane.js → arc-plane.ts} +203 -143
  15. package/Math/juction/{line-sphere.js → line-sphere.ts} +32 -22
  16. package/Math/juction/{plane-plane.js → plane-plane.ts} +62 -53
  17. package/Math/{line.js → line.ts} +84 -52
  18. package/Math/matrix4.ts +0 -0
  19. package/Math/mesh/mapbox-delaunay.d.ts +74 -0
  20. package/Math/{methods.js → methods.ts} +182 -107
  21. package/Math/{plane.js → plane.ts} +92 -56
  22. package/Math/{quaternion.js → quaternion.ts} +128 -106
  23. package/Math/roadmap.md +10 -0
  24. package/Math/templete-shapes/{grid-visually-equal.js → grid-visually-equal.ts} +118 -65
  25. package/Math/tessellation/constants.ts +1 -0
  26. package/Math/tessellation/methods.ts +79 -0
  27. package/Math/tessellation/nearest-value-padding.ts +147 -0
  28. package/Math/tessellation/roadmap.md +48 -0
  29. package/Math/tessellation/spherical-triangle-area.ts +127 -0
  30. package/Math/tessellation/tile-merger.ts +578 -0
  31. package/Math/tessellation/triangle-tessellation.ts +533 -0
  32. package/Math/tessellation/types.ts +1 -0
  33. package/Math/types.ts +68 -0
  34. package/Math/utils.js +3 -2
  35. package/Math/{vec3.js → vec3.ts} +227 -151
  36. package/Math/xyz-tile.ts +26 -0
  37. package/algorithms/search-binary.js +14 -16
  38. package/altitude-locator/adaptors.js +0 -1
  39. package/altitude-locator/keymethod.js +0 -1
  40. package/altitude-locator/plugin.js +445 -345
  41. package/altitude-locator/types.js +26 -21
  42. package/compass-rose/compass-rose-padding-flat.js +274 -230
  43. package/compass-rose/{compass-text-writer.js → compass-text-writer.ts} +210 -155
  44. package/compass-rose/index.js +3 -3
  45. package/{constants.js → constants.ts} +8 -6
  46. package/heatwave/datamanager.js +168 -149
  47. package/heatwave/heatwave.js +261 -206
  48. package/heatwave/index.js +5 -5
  49. package/heatwave/isobar.js +340 -303
  50. package/heatwave/{texture-point-sampler.js → texture-point-sampler.ts} +220 -187
  51. package/investigation-tools/draw/tiles/adapters.ts +133 -0
  52. package/investigation-tools/draw/tiles/tiles.ts +162 -0
  53. package/jest.config.js +6 -7
  54. package/package.json +1 -1
  55. package/pin/pin-object-array1.js +381 -300
  56. package/pin/pin-point-totem1.js +77 -60
  57. package/programs/arrowfield/arrow-field.js +89 -60
  58. package/programs/arrowfield/logic.js +173 -141
  59. package/programs/data2legend/density-to-legend.js +86 -68
  60. package/programs/data2legend/point-to-density-texture.js +84 -67
  61. package/programs/float2legendwithratio/index.js +3 -2
  62. package/programs/float2legendwithratio/logic.js +144 -118
  63. package/programs/float2legendwithratio/object.js +141 -104
  64. package/programs/helpers/blender.js +73 -58
  65. package/programs/helpers/{fadeaway.js → fadeaway.ts} +73 -55
  66. package/programs/index.js +19 -20
  67. package/programs/line-on-globe/circle-accurate-3d.js +112 -85
  68. package/programs/line-on-globe/circle-accurate-flat.js +200 -148
  69. package/programs/line-on-globe/degree-padding-around-circle-3d.js +134 -102
  70. package/programs/line-on-globe/index.js +0 -1
  71. package/programs/line-on-globe/lines-color-instanced-flat.js +99 -80
  72. package/programs/line-on-globe/linestrip/data.ts +29 -0
  73. package/programs/line-on-globe/linestrip/{linestrip.js → linestrip.ts} +152 -93
  74. package/programs/line-on-globe/{naive-accurate-flexible.js → naive-accurate-flexible.ts} +175 -126
  75. package/programs/line-on-globe/util.js +8 -5
  76. package/programs/picking/pickable-polygon-renderer.js +129 -98
  77. package/programs/picking/pickable-renderer.js +130 -98
  78. package/programs/point-on-globe/element-globe-surface-glow.js +122 -93
  79. package/programs/point-on-globe/element-point-glow.js +114 -80
  80. package/programs/point-on-globe/square-pixel-point.js +139 -120
  81. package/programs/polygon-on-globe/roadmap.md +8 -0
  82. package/programs/polygon-on-globe/texture-dem-triangles.ts +290 -0
  83. package/programs/{programcache.js → programcache.ts} +134 -126
  84. package/programs/rings/index.js +1 -1
  85. package/programs/rings/partial-ring/{piece-of-pie.js → piece-of-pie.ts} +222 -152
  86. package/programs/totems/camera-totem-attactment-interface.ts +4 -0
  87. package/programs/totems/{camerauniformblock.js → camerauniformblock.ts} +326 -230
  88. package/programs/totems/{canvas-webglobe-info.js → canvas-webglobe-info.ts} +147 -132
  89. package/programs/totems/dem-textures-manager.ts +368 -0
  90. package/programs/totems/{globe-changes.js → globe-changes.ts} +79 -59
  91. package/programs/totems/gpu-selection-uniform-block.js +127 -99
  92. package/programs/totems/{index.js → index.ts} +2 -2
  93. package/programs/two-d/pixel-padding-for-compass.js +101 -87
  94. package/programs/util.js +19 -14
  95. package/programs/vectorfields/logics/{constants.js → constants.ts} +5 -4
  96. package/programs/vectorfields/logics/drawrectangleparticles.ts +182 -0
  97. package/programs/vectorfields/logics/index.js +4 -2
  98. package/programs/vectorfields/logics/particle-ubo.ts +23 -0
  99. package/programs/vectorfields/logics/{pixelbased.js → pixelbased.ts} +119 -84
  100. package/programs/vectorfields/logics/ubo.js +57 -51
  101. package/programs/vectorfields/{pingpongbuffermanager.js → pingpongbuffermanager.ts} +113 -73
  102. package/publish.bat +62 -0
  103. package/range-tools-on-terrain/bearing-line/{adapters.js → adapters.ts} +154 -114
  104. package/range-tools-on-terrain/bearing-line/{plugin.js → plugin.ts} +569 -457
  105. package/range-tools-on-terrain/bearing-line/types.ts +65 -0
  106. package/range-tools-on-terrain/circle-line-chain/{adapters.js → adapters.ts} +104 -85
  107. package/range-tools-on-terrain/circle-line-chain/{chain-list-map.js → chain-list-map.ts} +446 -382
  108. package/range-tools-on-terrain/circle-line-chain/{plugin.js → plugin.ts} +607 -464
  109. package/range-tools-on-terrain/circle-line-chain/types.ts +43 -0
  110. package/range-tools-on-terrain/range-ring/{adapters.js → adapters.ts} +114 -93
  111. package/range-tools-on-terrain/range-ring/{enum.js → enum.ts} +2 -2
  112. package/range-tools-on-terrain/range-ring/{plugin.js → plugin.ts} +444 -377
  113. package/range-tools-on-terrain/range-ring/rangeringangletext.ts +396 -0
  114. package/range-tools-on-terrain/range-ring/types.ts +30 -0
  115. package/semiplugins/interface.ts +14 -0
  116. package/semiplugins/lightweight/{line-plugin.js → line-plugin.ts} +342 -221
  117. package/semiplugins/lightweight/{piece-of-pie-plugin.js → piece-of-pie-plugin.ts} +275 -200
  118. package/semiplugins/shape-on-terrain/{arc-plugin.js → arc-plugin.ts} +616 -472
  119. package/semiplugins/shape-on-terrain/{circle-plugin.js → circle-plugin.ts} +588 -444
  120. package/semiplugins/shape-on-terrain/goal.md +12 -0
  121. package/semiplugins/shape-on-terrain/{padding-1-degree.js → padding-1-degree.ts} +713 -539
  122. package/semiplugins/shape-on-terrain/terrain-polygon/adapters.ts +69 -0
  123. package/semiplugins/shape-on-terrain/terrain-polygon/data/cache-shortcuts.md +20 -0
  124. package/semiplugins/shape-on-terrain/terrain-polygon/data/cache.ts +149 -0
  125. package/semiplugins/shape-on-terrain/terrain-polygon/data/index-polygon-map.ts +58 -0
  126. package/semiplugins/shape-on-terrain/terrain-polygon/data/manager.ts +4 -0
  127. package/semiplugins/shape-on-terrain/terrain-polygon/data/master-worker.js +196 -0
  128. package/semiplugins/shape-on-terrain/terrain-polygon/data/master-worker.ts +209 -0
  129. package/semiplugins/shape-on-terrain/terrain-polygon/data/polygon-to-triangles.ts +144 -0
  130. package/semiplugins/shape-on-terrain/terrain-polygon/data/random.ts +165 -0
  131. package/semiplugins/shape-on-terrain/terrain-polygon/data/readme.md +5 -0
  132. package/semiplugins/shape-on-terrain/terrain-polygon/data/types.ts +37 -0
  133. package/semiplugins/shape-on-terrain/terrain-polygon/data/worker-contact.ts +81 -0
  134. package/semiplugins/shape-on-terrain/terrain-polygon/data/worker.js +146 -0
  135. package/semiplugins/shape-on-terrain/terrain-polygon/notes.md +90 -0
  136. package/semiplugins/shape-on-terrain/terrain-polygon/terrain-polygon.ts +265 -0
  137. package/semiplugins/shape-on-terrain/terrain-polygon/types.ts +69 -0
  138. package/semiplugins/shell/bbox-renderer/index.ts +2 -0
  139. package/semiplugins/shell/bbox-renderer/{logic.js → logic.ts} +273 -249
  140. package/semiplugins/shell/bbox-renderer/object.ts +129 -0
  141. package/semiplugins/type.ts +8 -0
  142. package/semiplugins/utility/{container-plugin.js → container-plugin.ts} +126 -94
  143. package/semiplugins/utility/{object-pass-container-plugin.js → object-pass-container-plugin.ts} +101 -80
  144. package/shaders/fragment-toy/firework.js +1 -1
  145. package/shaders/fragment-toy/singularity.js +5 -2
  146. package/terrain-plugin.mmd +83 -0
  147. package/tests/Math/arc-sampling-test.js +367 -0
  148. package/tests/Math/arc-sampling-test.ts +429 -0
  149. package/tests/Math/arc.test.ts +77 -0
  150. package/tests/Math/junction/arc-limit.test.ts +7 -0
  151. package/tests/Math/junction/arc-plane-points.test.ts +196 -0
  152. package/tests/Math/junction/arc-plane.test.ts +172 -0
  153. package/tests/Math/junction/line-sphere.test.ts +127 -0
  154. package/tests/Math/junction/plane-plane.test.ts +91 -0
  155. package/tests/Math/plane-test.ts +17 -0
  156. package/tests/Math/plane.test.ts +43 -0
  157. package/tests/Math/vec3.test.ts +33 -0
  158. package/tracks/point-heat-map/adaptors/timetracksplugin-format-to-this.js +78 -63
  159. package/tracks/point-heat-map/index.js +0 -1
  160. package/tracks/point-heat-map/plugin-webworker.js +148 -121
  161. package/tracks/point-heat-map/point-to-heat-map-flow.js +150 -121
  162. package/tracks/point-heat-map/readme.md +15 -0
  163. package/tracks/point-tracks/key-methods.js +3 -2
  164. package/tracks/point-tracks/plugin.js +487 -393
  165. package/tracks/timetracks/adaptors-line-strip.js +79 -65
  166. package/tracks/timetracks/plugin-line-strip.js +295 -240
  167. package/tracks/timetracks/program-line-strip.js +495 -411
  168. package/tracks/timetracks/programpoint-line-strip.js +137 -109
  169. package/tracks/timetracks/readme.md +1 -0
  170. package/tsconfig.json +22 -0
  171. package/types/@pirireis/webglobe.d.ts +102 -0
  172. package/types/delaunator.d.ts +40 -0
  173. package/types/earcut.d.ts +11 -0
  174. package/types/rbush.d.ts +57 -0
  175. package/types.ts +319 -0
  176. package/util/account/bufferoffsetmanager.js +209 -176
  177. package/util/account/create-buffermap-orchastration.ts +85 -0
  178. package/util/account/index.js +6 -3
  179. package/util/account/single-attribute-buffer-management/{buffer-manager.js → buffer-manager.ts} +151 -117
  180. package/util/account/single-attribute-buffer-management/{buffer-orchestrator.js → buffer-orchestrator.ts} +238 -212
  181. package/util/account/single-attribute-buffer-management/{buffer-orchestrator1.js → buffer-orchestrator1.ts} +184 -159
  182. package/util/account/single-attribute-buffer-management/{index.js → index.ts} +11 -4
  183. package/util/account/single-attribute-buffer-management/{object-store.js → object-store.ts} +76 -55
  184. package/util/account/single-attribute-buffer-management/types.ts +43 -0
  185. package/util/account/util.js +22 -18
  186. package/util/algorithms/index.js +0 -1
  187. package/util/algorithms/search-binary.js +26 -25
  188. package/util/build-strategy/{static-dynamic.js → static-dynamic.ts} +50 -41
  189. package/util/check/index.js +0 -1
  190. package/util/check/typecheck.ts +74 -0
  191. package/util/{frame-counter-trigger.js → frame-counter-trigger.ts} +99 -84
  192. package/util/geometry/{index.js → index.ts} +155 -121
  193. package/util/gl-util/buffer/{attribute-loader.js → attribute-loader.ts} +84 -62
  194. package/util/gl-util/buffer/{index.js → index.ts} +6 -3
  195. package/util/gl-util/draw-options/{methods.js → methods.ts} +47 -32
  196. package/util/gl-util/uniform-block/{manager.js → manager.ts} +232 -190
  197. package/util/{webglobe/gldefaultstates.js → globe-default-gl-states.ts} +5 -4
  198. package/util/helper-methods.ts +9 -0
  199. package/util/index.js +9 -10
  200. package/util/interpolation/index.js +0 -1
  201. package/util/interpolation/timetrack/index.js +9 -2
  202. package/util/interpolation/timetrack/timetrack-interpolator.js +94 -79
  203. package/util/interpolation/timetrack/web-worker.js +51 -46
  204. package/util/picking/{fence.js → fence.ts} +47 -41
  205. package/util/picking/picker-displayer.ts +226 -0
  206. package/util/programs/draw-from-pixel-coords.js +201 -164
  207. package/util/programs/{draw-texture-on-canvas.js → draw-texture-on-canvas.ts} +92 -67
  208. package/util/programs/supersampletotextures.js +130 -97
  209. package/util/programs/texturetoglobe.js +153 -128
  210. package/util/shaderfunctions/{geometrytransformations.js → geometrytransformations.ts} +169 -41
  211. package/util/shaderfunctions/index.js +2 -2
  212. package/util/shaderfunctions/nodata.js +4 -2
  213. package/util/shaderfunctions/noisefunctions.js +10 -7
  214. package/util/{webglobjectbuilders.js → webglobjectbuilders.ts} +446 -358
  215. package/vectorfield/arrowfield/adaptor.js +11 -11
  216. package/vectorfield/arrowfield/index.js +3 -3
  217. package/vectorfield/arrowfield/plugin.js +128 -83
  218. package/vectorfield/waveparticles/adaptor.js +16 -15
  219. package/vectorfield/waveparticles/index.js +3 -3
  220. package/vectorfield/waveparticles/plugin.ts +506 -0
  221. package/vectorfield/wind/adapters/image-to-fields.ts +74 -0
  222. package/vectorfield/wind/adapters/types.ts +12 -0
  223. package/vectorfield/wind/{imagetovectorfieldandmagnitude.js → imagetovectorfieldandmagnitude.ts} +78 -56
  224. package/vectorfield/wind/index.js +5 -5
  225. package/vectorfield/wind/plugin-persistant copy.ts +461 -0
  226. package/vectorfield/wind/plugin-persistant.ts +483 -0
  227. package/vectorfield/wind/plugin.js +883 -671
  228. package/vectorfield/wind/vectorfieldimage.js +27 -23
  229. package/write-text/{context-text-bulk.js → context-text-bulk.ts} +285 -200
  230. package/write-text/context-text3.ts +252 -0
  231. package/write-text/{context-text4.js → context-text4.ts} +231 -145
  232. package/write-text/context-textDELETE.js +125 -94
  233. package/write-text/objectarraylabels/{index.js → index.ts} +2 -2
  234. package/write-text/objectarraylabels/objectarraylabels.d.ts +72 -0
  235. package/write-text/objectarraylabels/objectarraylabels.js +247 -200
  236. package/Math/matrix4.js +0 -1
  237. package/Math/tessellation/earcut/adapters.js +0 -37
  238. package/Math/tessellation/hybrid-triangle-tessellation-meta.js +0 -123
  239. package/Math/tessellation/methods.js +0 -46
  240. package/Math/tessellation/shred-input.js +0 -18
  241. package/Math/tessellation/tile-merger.js +0 -56
  242. package/Math/tessellation/tiler.js +0 -50
  243. package/Math/tessellation/triangle-tessellation-meta.js +0 -516
  244. package/Math/tessellation/triangle-tessellation.js +0 -14
  245. package/Math/tessellation/types.js +0 -1
  246. package/Math/tessellation/zoom-catch.js +0 -1
  247. package/Math/types.js +0 -1
  248. package/programs/line-on-globe/linestrip/data.js +0 -4
  249. package/programs/polygon-on-globe/partial-tesselation.js +0 -1
  250. package/programs/polygon-on-globe/texture-dem-triangle-test-plugin-triangle.js +0 -204
  251. package/programs/polygon-on-globe/texture-dem-triangle-test-plugin.js +0 -118
  252. package/programs/polygon-on-globe/texture-dem-triangles.js +0 -236
  253. package/programs/vectorfields/logics/drawrectangleparticles.js +0 -112
  254. package/programs/vectorfields/logics/ubo-new.js +0 -25
  255. package/range-tools-on-terrain/bearing-line/types.js +0 -1
  256. package/range-tools-on-terrain/circle-line-chain/types.js +0 -1
  257. package/range-tools-on-terrain/range-ring/rangeringangletext.js +0 -331
  258. package/range-tools-on-terrain/range-ring/types.js +0 -9
  259. package/semiplugins/interface.js +0 -1
  260. package/semiplugins/shape-on-terrain/terrain-cover/texture-dem-cover.js +0 -1
  261. package/semiplugins/shell/bbox-renderer/index.js +0 -2
  262. package/semiplugins/shell/bbox-renderer/object.js +0 -65
  263. package/semiplugins/type.js +0 -1
  264. package/types.js +0 -19
  265. package/util/account/create-buffermap-orchastration.js +0 -39
  266. package/util/account/single-attribute-buffer-management/types.js +0 -1
  267. package/util/check/typecheck.js +0 -66
  268. package/util/gl-util/uniform-block/types.js +0 -1
  269. package/util/picking/picker-displayer.js +0 -134
  270. package/util/webglobe/index.js +0 -2
  271. package/util/webglobe/rasteroverlay.js +0 -76
  272. package/vectorfield/waveparticles/plugin.js +0 -290
  273. package/write-text/attached-text-writer.js +0 -95
  274. package/write-text/context-text3.js +0 -167
@@ -1,464 +1,607 @@
1
- import { CircleOnTerrainPlugin } from "../../semiplugins/shape-on-terrain/circle-plugin";
2
- import { LinePlugin } from "../../semiplugins/lightweight/line-plugin";
3
- import { ArcOnTerrainPlugin } from "../../semiplugins/shape-on-terrain/arc-plugin";
4
- import { keyMethod, lineDataAdaptor, arcDataAdaptor, circleDataAdaptor, getOpacity } from "./adapters";
5
- import { ContextTextWriter3 } from "../../write-text/context-text3";
6
- import { ChainListMap } from "./chain-list-map";
7
- import { mapGetOrThrow } from "../../util/check/typecheck";
8
- const textWriterGetOrThrow = mapGetOrThrow("textWriterIDs is invalid");
9
- export class CircleLineChainPlugin {
10
- id;
11
- globe = null;
12
- gl = null;
13
- circlePlugin = null;
14
- linePlugin = null;
15
- arcPlugin = null;
16
- _freed = false;
17
- _opacities;
18
- _drawCircleOn = true;
19
- _textWritersMap;
20
- _textDataPreAdaptor = undefined;
21
- _chainListMap;
22
- _semiPluginOptions = {
23
- circleOnTerrainOptions: {
24
- variativeColorsOn: false,
25
- defaultColor: [1, 1, 1, 1],
26
- defaultHeightFromGroundIn3D: 30,
27
- isMSL: false
28
- },
29
- arcOnTerrainOptions: {
30
- flatViewOn: true,
31
- globeViewOn: true,
32
- variativeColorsOn: false,
33
- defaultColor: [1, 1, 1, 1],
34
- defaultHeightFromGroundIn3D: 0,
35
- vertexCount: 32,
36
- cameraAttractionIsOn: true, // If true, camera attraction is enabled else evenly distributed arc points are used
37
- isMSL: false, // If true, no elevation of terrain
38
- },
39
- lineOptions: {
40
- flatViewOn: true,
41
- globeViewOn: true,
42
- variativeColorsOn: false,
43
- defaultColor: [1, 1, 1, 1],
44
- dashedLineOpacityVariativeOn: false,
45
- dashedLineRatioVariativeOn: false,
46
- bufferType: "DYNAMIC_DRAW",
47
- opacity: 1.0,
48
- }
49
- };
50
- constructor(id, { drawCircleOn, textWritersMap, textDataPreAdaptor, opacities, arcOnTerrainOptions, circleOnTerrainOptions, lineOptions } = {}) {
51
- const defaults = {
52
- drawCircleOn: true,
53
- textWritersMap: new Map(),
54
- textDataPreAdaptor: undefined,
55
- opacities: {
56
- general: 1,
57
- circle: null,
58
- flatStraightLine: null,
59
- flatGreatCircle: null,
60
- globeArcFitsTerrain: null,
61
- globeArcNotFitsTerrain: null
62
- }
63
- };
64
- const finalOpacities = { ...defaults.opacities, ...opacities };
65
- const config = {
66
- ...defaults,
67
- drawCircleOn: drawCircleOn ?? defaults.drawCircleOn,
68
- textWritersMap: textWritersMap ?? defaults.textWritersMap,
69
- textDataPreAdaptor: textDataPreAdaptor ?? defaults.textDataPreAdaptor,
70
- opacities: finalOpacities
71
- };
72
- this._semiPluginOptions.circleOnTerrainOptions = {
73
- ...this._semiPluginOptions.circleOnTerrainOptions,
74
- ...circleOnTerrainOptions
75
- };
76
- this._semiPluginOptions.arcOnTerrainOptions = {
77
- ...this._semiPluginOptions.arcOnTerrainOptions,
78
- ...arcOnTerrainOptions
79
- };
80
- this._semiPluginOptions.lineOptions = {
81
- ...this._semiPluginOptions.lineOptions,
82
- ...lineOptions
83
- };
84
- this.id = id;
85
- this._drawCircleOn = config.drawCircleOn;
86
- this._textWritersMap = config.textWritersMap;
87
- this._textDataPreAdaptor = config.textDataPreAdaptor;
88
- this._chainListMap = new ChainListMap(keyMethod);
89
- this._opacities = config.opacities;
90
- this._checktextWritersMap(this._textWritersMap);
91
- this._textWritersMap.forEach((writer) => {
92
- writer.setKeyAdaptor((v) => v.__identity__);
93
- });
94
- }
95
- // API
96
- insertBulk(chains, { textWriterIDs = [] } = {}) {
97
- if (this._freed) {
98
- console.warn("CircleLineChainPlugin is freed, cannot insert bulk.");
99
- return;
100
- }
101
- if (chains.length === 0)
102
- return;
103
- const chainKeys = [];
104
- const chainsToClean = [];
105
- for (const { chainKey } of chains) {
106
- if (this._chainListMap.hasChain(chainKey)) {
107
- chainsToClean.push(chainKey);
108
- }
109
- }
110
- this._cleanChainsFromSemiPlugins(chainsToClean);
111
- for (const { chainKey, chainProperties, nodes } of chains) {
112
- if (!chainKey || !chainProperties || !nodes || nodes.length === 0) {
113
- console.warn("Invalid chain data, skipping insertion.");
114
- continue;
115
- }
116
- this._chainListMap.setChain(chainKey, nodes);
117
- this._chainListMap.setChainProperties(chainKey, chainProperties);
118
- chainKeys.push(chainKey);
119
- }
120
- // Reconstruct chains
121
- this._reconstructChains(chainKeys);
122
- // Update texts
123
- this._updateTexts(chainKeys, textWriterIDs);
124
- this.globe?.DrawRender();
125
- }
126
- addNode(node, chainKey, { theNodeKeyFront, textWriterIDs = [] } = {}) {
127
- if (this._freed) {
128
- console.warn("CircleLineChainPlugin is freed, cannot add node.");
129
- return;
130
- }
131
- this._cleanChainsFromSemiPlugins([chainKey]);
132
- this._chainListMap.addNode(node, chainKey, theNodeKeyFront);
133
- this._reconstructChains([chainKey]);
134
- this._updateTexts([chainKey], textWriterIDs);
135
- this.globe?.DrawRender();
136
- }
137
- getChain(chainKey) {
138
- return this._chainListMap.getNodes(chainKey);
139
- }
140
- setDrawCircleOn(value) {
141
- if (this._freed) {
142
- console.warn("CircleLineChainPlugin is freed, cannot set drawCircleOn.");
143
- return;
144
- }
145
- this._drawCircleOn = value;
146
- this.globe?.DrawRender();
147
- }
148
- setOpacities(opacities) {
149
- if (this._freed) {
150
- console.warn("CircleLineChainPlugin is freed, cannot set opacities.");
151
- return;
152
- }
153
- this._opacities = {
154
- ...this._opacities,
155
- ...opacities
156
- };
157
- this.globe?.DrawRender();
158
- }
159
- setElevationMode(mode) {
160
- if (this._freed) {
161
- console.warn("CircleLineChainPlugin is freed, cannot set elevation mode.");
162
- return;
163
- }
164
- this.arcPlugin?.setElevationMode(mode);
165
- this.circlePlugin?.setElevationMode(mode);
166
- this.globe?.DrawRender();
167
- }
168
- deleteChains(chainKeys) {
169
- if (this._freed) {
170
- console.warn("CircleLineChainPlugin is freed, cannot delete chains.");
171
- return;
172
- }
173
- // type check chainKeys
174
- if (!Array.isArray(chainKeys) || chainKeys.some(key => typeof key !== "string")) {
175
- console.warn("Invalid chainKeys array.");
176
- return;
177
- }
178
- for (const chainKey of chainKeys) {
179
- const keys = this._chainListMap.deleteChainAndReturnChainKeys(chainKey, this._textWritersMap);
180
- if (keys.length <= 1) {
181
- console.warn(`Deleted chain ${chainKey}, was too small to be displayed.`);
182
- continue;
183
- }
184
- keys.pop(); // Remove the last key which which is destination of the last circle
185
- this.linePlugin?.deleteBulk(keys);
186
- this.arcPlugin?.deleteBulk(keys);
187
- this.circlePlugin?.deleteBulk(keys);
188
- this._updateTexts(chainKeys, Array.from(this._textWritersMap.keys()));
189
- }
190
- this.globe?.DrawRender();
191
- }
192
- deleteNodes(keysAndNodes) {
193
- if (this._freed) {
194
- console.warn("CircleLineChainPlugin is freed, cannot delete nodes.");
195
- return;
196
- }
197
- const chainKeysToReconstruct = keysAndNodes.map(({ chainKey }) => chainKey);
198
- // this._chainListMap.deleteTexts(chainKeysToReconstruct, this._textWritersMap); // TODO: delete this method from chain-list-map
199
- this._cleanChainsFromSemiPlugins(chainKeysToReconstruct);
200
- keysAndNodes.forEach(({ chainKey, nodeKeys }) => {
201
- this._chainListMap.deleteNodesBelongToAChain(chainKey, nodeKeys);
202
- });
203
- this._reconstructChains(chainKeysToReconstruct);
204
- this._updateTexts(chainKeysToReconstruct, Array.from(this._textWritersMap.keys()));
205
- this.globe?.DrawRender();
206
- }
207
- updateNodesProperties(chainKey, nodesAndPropertyList, { textWriterIDs = [] } = {}) {
208
- if (this._freed) {
209
- console.warn("CircleLineChainPlugin is freed, cannot update nodes properties.");
210
- return;
211
- }
212
- const hasChain = this._chainListMap.hasChain(chainKey);
213
- if (!hasChain) {
214
- console.warn(`Chain with key ${chainKey} not found.`);
215
- return;
216
- }
217
- this._chainListMap.updateNodesProperties(chainKey, nodesAndPropertyList);
218
- this._cleanChainsFromSemiPlugins([chainKey]);
219
- this._reconstructChains([chainKey]);
220
- this._updateTexts([chainKey], textWriterIDs);
221
- this.globe?.DrawRender();
222
- }
223
- updateChainDrawOptionsProperties(chainKey, drawOptions) {
224
- if (this._freed) {
225
- console.warn("CircleLineChainPlugin is freed, cannot update chain draw options properties.");
226
- return;
227
- }
228
- const chain = this._chainListMap.getChain(chainKey);
229
- if (!chain) {
230
- console.warn(`Chain with key ${chainKey} not found.`);
231
- return;
232
- }
233
- const { nodes } = chain;
234
- nodes.forEach((node) => {
235
- if (drawOptions.circleOn !== undefined) {
236
- node.circleOn = drawOptions.circleOn;
237
- }
238
- if (drawOptions.arcOn !== undefined) {
239
- node.arcOn = drawOptions.arcOn;
240
- }
241
- if (drawOptions.line !== undefined) {
242
- node.lineOn = drawOptions.line;
243
- }
244
- });
245
- this._cleanChainsFromSemiPlugins([chainKey]);
246
- this._reconstructChains([chainKey]);
247
- this._updateTexts([chainKey], Array.from(this._textWritersMap.keys()));
248
- this.globe?.DrawRender();
249
- }
250
- updateCoordinatesBulk(chains, { textWriterIDs = [] } = {}) {
251
- if (this._freed) {
252
- console.warn("CircleLineChainPlugin is freed, cannot update coordinates.");
253
- return;
254
- }
255
- const chainKeys = [];
256
- for (const chain of chains) {
257
- const { chainKey, nodes } = chain;
258
- chainKeys.push(chainKey);
259
- nodes.forEach((node, index) => {
260
- this._chainListMap.updateCoordsinatesOfNode(node, chainKey);
261
- });
262
- }
263
- this._updateTexts(chainKeys, textWriterIDs);
264
- this._reconstructChains(chainKeys);
265
- }
266
- updateNodeCoordinates(node, chainKey, { textWriterIDs = [] } = {}) {
267
- if (this._freed) {
268
- console.warn("CircleLineChainPlugin is freed, cannot update node coordinates.");
269
- return;
270
- }
271
- this._chainListMap.updateCoordsinatesOfNode(node, chainKey);
272
- if (textWriterIDs && textWriterIDs.length > 0) {
273
- this._updateTexts([chainKey], textWriterIDs);
274
- }
275
- this._reconstructChains([chainKey]);
276
- this.globe?.DrawRender();
277
- }
278
- updateChainProperties(chainKey, properties) {
279
- if (this._freed) {
280
- console.warn("CircleLineChainPlugin is freed, cannot update chain properties.");
281
- return;
282
- }
283
- this._chainListMap.updateChainProperties(chainKey, properties);
284
- this._cleanChainsFromSemiPlugins([chainKey]);
285
- this._reconstructChains([chainKey]);
286
- this._updateTexts([chainKey], Array.from(this._textWritersMap.keys()));
287
- this.globe?.DrawRender();
288
- }
289
- updateText(textWriterIDs, chainKeys = null) {
290
- if (this._freed) {
291
- console.warn("CircleLineChainPlugin is freed, cannot update text.");
292
- return;
293
- }
294
- if (!chainKeys) {
295
- chainKeys = Array.from(this._chainListMap.getAllChainKeysIterator());
296
- }
297
- this._updateTexts(chainKeys, textWriterIDs);
298
- this.globe?.DrawRender();
299
- }
300
- setDefaultSemiPluginColor(semiPluginName, color) {
301
- if (semiPluginName === "ALL") {
302
- this._semiPluginOptions.circleOnTerrainOptions.defaultColor = color;
303
- this._semiPluginOptions.arcOnTerrainOptions.defaultColor = color;
304
- this._semiPluginOptions.lineOptions.defaultColor = color;
305
- this.circlePlugin?.setDefaultColor(color);
306
- this.arcPlugin?.setDefaultColor(color);
307
- this.linePlugin?.setDefaultColor(color);
308
- return;
309
- }
310
- switch (semiPluginName) {
311
- case "circleOnTerrain":
312
- this._semiPluginOptions.circleOnTerrainOptions.defaultColor = color;
313
- this.circlePlugin?.setDefaultColor(color);
314
- break;
315
- case "arcOnTerrain":
316
- this._semiPluginOptions.arcOnTerrainOptions.defaultColor = color;
317
- this.arcPlugin?.setDefaultColor(color);
318
- break;
319
- case "line":
320
- this._semiPluginOptions.lineOptions.defaultColor = color;
321
- this.linePlugin?.setDefaultColor(color);
322
- break;
323
- default:
324
- throw new Error(`Unknown semi-plugin name: ${semiPluginName}`);
325
- }
326
- }
327
- // IMPLICIT METHODS
328
- _checktextWritersMap(textWritersMap) {
329
- if (!(textWritersMap instanceof Map))
330
- throw new Error("textWritersMap is not an instance of Map");
331
- textWritersMap.forEach((v) => {
332
- if (!(v instanceof ContextTextWriter3))
333
- throw new Error("textWritersMap element is not an instance of ContextTextWriter3");
334
- });
335
- }
336
- _updateTexts(chainKeys, textWriterIDs) {
337
- if (textWriterIDs.length === 0)
338
- return;
339
- const textWriters = textWriterGetOrThrow(this._textWritersMap, textWriterIDs);
340
- chainKeys.forEach((chainKey) => {
341
- this._chainListMap.textUpdate(chainKey, textWriters, this._textDataPreAdaptor);
342
- });
343
- }
344
- _cleanChainsFromSemiPlugins(chainKeys) {
345
- if (!this.globe || !this.gl) {
346
- throw new Error("Globe or WebGL context is not initialized");
347
- }
348
- for (const chainKey of chainKeys) {
349
- // Clean chains from text writers
350
- const nodeKeys = this._chainListMap.getNodeKeysOfChain(chainKey);
351
- this._textWritersMap.forEach((writer) => {
352
- writer.deleteTextBulk(nodeKeys);
353
- });
354
- nodeKeys.pop(); // Remove the last key which is destination of the last circle
355
- // Clean chains from semi-plugins
356
- this.circlePlugin?.deleteBulk(nodeKeys);
357
- this.linePlugin?.deleteBulk(nodeKeys);
358
- this.arcPlugin?.deleteBulk(nodeKeys);
359
- }
360
- }
361
- _reconstructChains(chainKeys) {
362
- // TODO: this is core
363
- // Get chain nodes
364
- const globe = this.globe;
365
- if (!globe || !this.gl) {
366
- throw new Error("Globe or WebGL context is not initialized");
367
- }
368
- for (let chainKey of chainKeys) {
369
- const chain = this._chainListMap.getChain(chainKey);
370
- if (!chain) {
371
- console.warn(`Chain with key ${chainKey} not found.`);
372
- continue;
373
- }
374
- const lineInput = lineDataAdaptor(chain);
375
- const arcInput = arcDataAdaptor(chain);
376
- const circleInput = circleDataAdaptor(globe, chain);
377
- this.linePlugin?.insertBulk(lineInput);
378
- this.arcPlugin?.insertBulk(arcInput);
379
- this.circlePlugin?.insertBulk(circleInput);
380
- }
381
- }
382
- // GLOBE INTERFACE METHODS
383
- init(globe, gl) {
384
- this.globe = globe;
385
- this.gl = gl;
386
- // Initialize sub-plugins with unique IDs
387
- this.circlePlugin = new CircleOnTerrainPlugin(`${this.id}_unregistered_circles`, this._semiPluginOptions.circleOnTerrainOptions);
388
- this.linePlugin = new LinePlugin(`${this.id}_unregistered_lines`, this._semiPluginOptions.lineOptions);
389
- this.arcPlugin = new ArcOnTerrainPlugin(`${this.id}_unregistered_arcs`, this._semiPluginOptions.arcOnTerrainOptions);
390
- this.circlePlugin.init(globe, gl);
391
- this.linePlugin.init(globe, gl);
392
- this.arcPlugin.init(globe, gl);
393
- }
394
- draw3D() {
395
- if (this._freed) {
396
- console.warn("CircleLineChainPlugin is freed, cannot draw.");
397
- return;
398
- }
399
- const { globe, gl } = this;
400
- if (!globe || !gl) {
401
- console.warn("Globe or WebGL context is not initialized, cannot draw.");
402
- return;
403
- }
404
- const circleOpacity = getOpacity(this._opacities, "circle");
405
- if (this._drawCircleOn && circleOpacity !== 0) {
406
- this.circlePlugin?.setPluginOpacity(circleOpacity, false);
407
- this.circlePlugin?.draw3D();
408
- }
409
- const currentGeometry = globe.api_GetCurrentGeometry();
410
- switch (currentGeometry) {
411
- case 0: {
412
- // globe view
413
- const lineOpacity = getOpacity(this._opacities, "globeArc");
414
- if (lineOpacity !== 0) {
415
- this.linePlugin?.setPluginOpacity(lineOpacity, false);
416
- this.linePlugin?.draw3D();
417
- }
418
- const arcOpacity = getOpacity(this._opacities, "globeArcFitsTerrain");
419
- if (arcOpacity !== 0) {
420
- this.arcPlugin?.setPluginOpacity(arcOpacity, false);
421
- this.arcPlugin?.draw3D();
422
- }
423
- break;
424
- }
425
- case 1: {
426
- // flat view
427
- const lineOpacity = getOpacity(this._opacities, "flatStraightLine");
428
- if (lineOpacity !== 0) {
429
- this.linePlugin?.setPluginOpacity(lineOpacity);
430
- this.linePlugin?.draw3D();
431
- }
432
- const arcOpacity = getOpacity(this._opacities, "flatGreatCircleLine");
433
- if (arcOpacity !== 0) {
434
- this.arcPlugin?.setPluginOpacity(arcOpacity);
435
- this.arcPlugin?.draw3D();
436
- }
437
- break;
438
- }
439
- default: {
440
- throw new Error("Unknown geometry type, Implementation need on Circle-Line-Chain Plugin");
441
- }
442
- }
443
- this._textWritersMap.forEach((writer) => {
444
- writer.draw();
445
- });
446
- }
447
- free() {
448
- if (this._freed)
449
- return;
450
- this._freed = true;
451
- // Free sub-plugins
452
- this.circlePlugin?.free();
453
- this.linePlugin?.free();
454
- this.arcPlugin?.free();
455
- // Clear text writers map
456
- this._textWritersMap.clear();
457
- // Clear references
458
- this.globe = null;
459
- this.gl = null;
460
- this.circlePlugin = null;
461
- this.linePlugin = null;
462
- this.arcPlugin = null;
463
- }
464
- }
1
+ import { Chain, Node, Opacities } from "./types";
2
+
3
+ import { CircleOnTerrainPlugin, CircleOnTerrainPluginOptions } from "../../semiplugins/shape-on-terrain/circle-plugin";
4
+ import { LinePlugin, LinePluginOptions } from "../../semiplugins/lightweight/line-plugin";
5
+ import { ArcOnTerrainPlugin, ArcOnTerrainPluginOptions } from "../../semiplugins/shape-on-terrain/arc-plugin";
6
+
7
+
8
+ import { keyMethod, lineDataAdaptor, arcDataAdaptor, circleDataAdaptor, getOpacity } from "./adapters";
9
+
10
+ import { Globe, PluginInterface, Color } from "../../types";
11
+ import { ContextTextWriter3 } from "../../write-text/context-text3";
12
+ import { ChainListMap } from "./chain-list-map";
13
+ import { mapGetOrThrow } from "../../util/check/typecheck";
14
+
15
+
16
+ const textWriterGetOrThrow = mapGetOrThrow("textWriterIDs is invalid");
17
+
18
+ export type DrawSemiPluginDraw = {
19
+ circleOn: boolean;
20
+ arcOn: boolean;
21
+ line: boolean;
22
+ };
23
+
24
+
25
+ export class CircleLineChainPlugin implements PluginInterface {
26
+ id: string;
27
+ globe: Globe | null = null;
28
+ gl: WebGL2RenderingContext | null = null;
29
+ circlePlugin: CircleOnTerrainPlugin | null = null;
30
+ linePlugin: LinePlugin | null = null;
31
+ arcPlugin: ArcOnTerrainPlugin | null = null;
32
+
33
+ private _freed: boolean = false;
34
+ private _opacities: Opacities;
35
+ private _drawCircleOn: boolean = true;
36
+ private _textWritersMap: Map<string, ContextTextWriter3>;
37
+ private _textDataPreAdaptor: ((item: Node, index: number, nodes: Node[]) => any) | undefined = undefined;
38
+ private _chainListMap: ChainListMap;
39
+ private _semiPluginOptions: {
40
+ circleOnTerrainOptions: Partial<CircleOnTerrainPluginOptions>;
41
+ arcOnTerrainOptions: Partial<ArcOnTerrainPluginOptions>;
42
+ lineOptions: Partial<LinePluginOptions>;
43
+ } = {
44
+ circleOnTerrainOptions: {
45
+ variativeColorsOn: false,
46
+ defaultColor: [1, 1, 1, 1],
47
+ defaultHeightFromGroundIn3D: 30,
48
+ isMSL: false
49
+ },
50
+ arcOnTerrainOptions: {
51
+ flatViewOn: true,
52
+ globeViewOn: true,
53
+ variativeColorsOn: false,
54
+ defaultColor: [1, 1, 1, 1],
55
+ defaultHeightFromGroundIn3D: 0,
56
+ vertexCount: 32,
57
+ cameraAttractionIsOn: true, // If true, camera attraction is enabled else evenly distributed arc points are used
58
+ isMSL: false, // If true, no elevation of terrain
59
+
60
+ },
61
+ lineOptions: {
62
+ flatViewOn: true,
63
+ globeViewOn: true,
64
+ variativeColorsOn: false,
65
+ defaultColor: [1, 1, 1, 1],
66
+ dashedLineOpacityVariativeOn: false,
67
+ dashedLineRatioVariativeOn: false,
68
+ bufferType: "DYNAMIC_DRAW",
69
+ opacity: 1.0,
70
+
71
+ }
72
+ }
73
+
74
+ constructor(id: string, {
75
+ drawCircleOn,
76
+ textWritersMap,
77
+ textDataPreAdaptor,
78
+ opacities,
79
+ arcOnTerrainOptions,
80
+ circleOnTerrainOptions,
81
+ lineOptions
82
+ }: {
83
+ drawCircleOn?: boolean;
84
+ textWritersMap?: Map<string, ContextTextWriter3>;
85
+ textDataPreAdaptor?: (item: Node, index: number, nodes: Node[]) => any | null;
86
+ opacities?: Opacities;
87
+ arcOnTerrainOptions?: Partial<ArcOnTerrainPluginOptions>;
88
+ circleOnTerrainOptions?: Partial<CircleOnTerrainPluginOptions>;
89
+ lineOptions?: Partial<LinePluginOptions>;
90
+ } = {}) {
91
+ const defaults = {
92
+ drawCircleOn: true,
93
+ textWritersMap: new Map<string, ContextTextWriter3>(),
94
+ textDataPreAdaptor: undefined,
95
+ opacities: {
96
+ general: 1,
97
+ circle: null,
98
+ flatStraightLine: null,
99
+ flatGreatCircle: null,
100
+ globeArcFitsTerrain: null,
101
+ globeArcNotFitsTerrain: null
102
+ }
103
+ };
104
+
105
+ const finalOpacities = { ...defaults.opacities, ...opacities };
106
+ const config = {
107
+ ...defaults,
108
+ drawCircleOn: drawCircleOn ?? defaults.drawCircleOn,
109
+ textWritersMap: textWritersMap ?? defaults.textWritersMap,
110
+ textDataPreAdaptor: textDataPreAdaptor ?? defaults.textDataPreAdaptor,
111
+ opacities: finalOpacities
112
+ };
113
+
114
+ this._semiPluginOptions.circleOnTerrainOptions = {
115
+ ...this._semiPluginOptions.circleOnTerrainOptions,
116
+ ...circleOnTerrainOptions
117
+ };
118
+ this._semiPluginOptions.arcOnTerrainOptions = {
119
+ ...this._semiPluginOptions.arcOnTerrainOptions,
120
+ ...arcOnTerrainOptions
121
+ };
122
+ this._semiPluginOptions.lineOptions = {
123
+ ...this._semiPluginOptions.lineOptions,
124
+ ...lineOptions
125
+ };
126
+
127
+ this.id = id;
128
+ this._drawCircleOn = config.drawCircleOn;
129
+ this._textWritersMap = config.textWritersMap;
130
+ this._textDataPreAdaptor = config.textDataPreAdaptor;
131
+ this._chainListMap = new ChainListMap(keyMethod);
132
+ this._opacities = config.opacities;
133
+
134
+ this._checktextWritersMap(this._textWritersMap);
135
+ this._textWritersMap.forEach((writer) => {
136
+ writer.setKeyAdaptor((v: any) => v.__identity__);
137
+ });
138
+ }
139
+
140
+
141
+ // API
142
+
143
+ insertBulk(chains: Chain[], { textWriterIDs = [] }: { textWriterIDs?: string[] } = {}): void {
144
+ if (this._freed) {
145
+ console.warn("CircleLineChainPlugin is freed, cannot insert bulk.");
146
+ return;
147
+ }
148
+ if (chains.length === 0) return;
149
+
150
+ const chainKeys = [];
151
+ const chainsToClean = []
152
+ for (const { chainKey } of chains) {
153
+ if (this._chainListMap.hasChain(chainKey)) {
154
+ chainsToClean.push(chainKey);
155
+ }
156
+
157
+ }
158
+ this._cleanChainsFromSemiPlugins(chainsToClean);
159
+
160
+ for (const { chainKey, chainProperties, nodes } of chains) {
161
+ if (!chainKey || !chainProperties || !nodes || nodes.length === 0) {
162
+ console.warn("Invalid chain data, skipping insertion.");
163
+ continue;
164
+ }
165
+ this._chainListMap.setChain(chainKey, nodes);
166
+ this._chainListMap.setChainProperties(chainKey, chainProperties);
167
+ chainKeys.push(chainKey);
168
+ }
169
+
170
+ // Reconstruct chains
171
+ this._reconstructChains(chainKeys);
172
+
173
+ // Update texts
174
+ this._updateTexts(chainKeys, textWriterIDs);
175
+ this.globe?.DrawRender();
176
+ }
177
+
178
+
179
+ addNode(node: Node, chainKey: string, { theNodeKeyFront, textWriterIDs = [] }: { theNodeKeyFront?: undefined | string, textWriterIDs?: string[] } = {}): void {
180
+ if (this._freed) {
181
+ console.warn("CircleLineChainPlugin is freed, cannot add node.");
182
+ return;
183
+ }
184
+ this._cleanChainsFromSemiPlugins([chainKey]);
185
+ this._chainListMap.addNode(node, chainKey, theNodeKeyFront)
186
+ this._reconstructChains([chainKey]);
187
+ this._updateTexts([chainKey], textWriterIDs);
188
+ this.globe?.DrawRender();
189
+ }
190
+
191
+
192
+ getChain(chainKey: string): Node[] | undefined {
193
+ return this._chainListMap.getNodes(chainKey);
194
+ }
195
+
196
+
197
+ setDrawCircleOn(value: boolean): void {
198
+ if (this._freed) {
199
+ console.warn("CircleLineChainPlugin is freed, cannot set drawCircleOn.");
200
+ return;
201
+ }
202
+ this._drawCircleOn = value;
203
+ this.globe?.DrawRender();
204
+ }
205
+
206
+
207
+
208
+ setOpacities(opacities: Partial<Opacities>): void {
209
+ if (this._freed) {
210
+ console.warn("CircleLineChainPlugin is freed, cannot set opacities.");
211
+ return;
212
+ }
213
+ this._opacities = {
214
+ ...this._opacities,
215
+ ...opacities
216
+ };
217
+ this.globe?.DrawRender();
218
+ }
219
+
220
+
221
+ setElevationMode(mode: "msl" | "agl"): void {
222
+ if (this._freed) {
223
+ console.warn("CircleLineChainPlugin is freed, cannot set elevation mode.");
224
+ return;
225
+ }
226
+ this.arcPlugin?.setElevationMode(mode);
227
+ this.circlePlugin?.setElevationMode(mode);
228
+
229
+ this.globe?.DrawRender();
230
+ }
231
+
232
+
233
+
234
+ deleteChains(chainKeys: string[]): void {
235
+ if (this._freed) {
236
+ console.warn("CircleLineChainPlugin is freed, cannot delete chains.");
237
+ return;
238
+ }
239
+ // type check chainKeys
240
+ if (!Array.isArray(chainKeys) || chainKeys.some(key => typeof key !== "string")) {
241
+ console.warn("Invalid chainKeys array.");
242
+ return;
243
+ }
244
+
245
+ for (const chainKey of chainKeys) {
246
+ const keys = this._chainListMap.deleteChainAndReturnChainKeys(chainKey, this._textWritersMap);
247
+ if (keys.length <= 1) {
248
+ console.warn(`Deleted chain ${chainKey}, was too small to be displayed.`);
249
+ continue;
250
+ }
251
+ keys.pop(); // Remove the last key which which is destination of the last circle
252
+ this.linePlugin?.deleteBulk(keys);
253
+ this.arcPlugin?.deleteBulk(keys);
254
+ this.circlePlugin?.deleteBulk(keys);
255
+
256
+ this._updateTexts(chainKeys, Array.from(this._textWritersMap.keys()));
257
+ }
258
+ this.globe?.DrawRender();
259
+ }
260
+
261
+
262
+ deleteNodes(keysAndNodes: Array<{
263
+ chainKey: string;
264
+ nodeKeys: string[];
265
+ }>): void {
266
+
267
+ if (this._freed) {
268
+ console.warn("CircleLineChainPlugin is freed, cannot delete nodes.");
269
+ return;
270
+ }
271
+ const chainKeysToReconstruct: string[] = keysAndNodes.map(({ chainKey }) => chainKey);
272
+ // this._chainListMap.deleteTexts(chainKeysToReconstruct, this._textWritersMap); // TODO: delete this method from chain-list-map
273
+ this._cleanChainsFromSemiPlugins(chainKeysToReconstruct);
274
+ keysAndNodes.forEach(({ chainKey, nodeKeys }) => {
275
+ this._chainListMap.deleteNodesBelongToAChain(chainKey, nodeKeys);
276
+ });
277
+ this._reconstructChains(chainKeysToReconstruct);
278
+ this._updateTexts(chainKeysToReconstruct, Array.from(this._textWritersMap.keys()));
279
+
280
+ this.globe?.DrawRender();
281
+ }
282
+
283
+
284
+ updateNodesProperties(chainKey: string,
285
+ nodesAndPropertyList: Pick<Node, "key" | "circleProperties" | "lineProperties" | "circleOn" | "arcOn" | "lineOn">[],
286
+ { textWriterIDs = [] }: { textWriterIDs?: string[] } = {}): void {
287
+ if (this._freed) {
288
+ console.warn("CircleLineChainPlugin is freed, cannot update nodes properties.");
289
+ return;
290
+ }
291
+ const hasChain = this._chainListMap.hasChain(chainKey);
292
+ if (!hasChain) {
293
+ console.warn(`Chain with key ${chainKey} not found.`);
294
+ return;
295
+ }
296
+ this._chainListMap.updateNodesProperties(chainKey, nodesAndPropertyList);
297
+ this._cleanChainsFromSemiPlugins([chainKey]);
298
+ this._reconstructChains([chainKey]);
299
+ this._updateTexts([chainKey], textWriterIDs);
300
+ this.globe?.DrawRender();
301
+ }
302
+
303
+
304
+ updateChainDrawOptionsProperties(chainKey: string,
305
+ drawOptions: Partial<DrawSemiPluginDraw>,
306
+ ): void {
307
+
308
+ if (this._freed) {
309
+ console.warn("CircleLineChainPlugin is freed, cannot update chain draw options properties.");
310
+ return;
311
+ }
312
+
313
+ const chain = this._chainListMap.getChain(chainKey);
314
+ if (!chain) {
315
+ console.warn(`Chain with key ${chainKey} not found.`);
316
+ return;
317
+ }
318
+ const { nodes } = chain;
319
+ nodes.forEach((node) => {
320
+ if (drawOptions.circleOn !== undefined) {
321
+ node.circleOn = drawOptions.circleOn;
322
+ }
323
+ if (drawOptions.arcOn !== undefined) {
324
+ node.arcOn = drawOptions.arcOn;
325
+ }
326
+ if (drawOptions.line !== undefined) {
327
+ node.lineOn = drawOptions.line;
328
+ }
329
+ });
330
+
331
+ this._cleanChainsFromSemiPlugins([chainKey]);
332
+ this._reconstructChains([chainKey]);
333
+ this._updateTexts([chainKey], Array.from(this._textWritersMap.keys()));
334
+ this.globe?.DrawRender();
335
+ }
336
+
337
+
338
+
339
+ updateCoordinatesBulk(chains: Pick<Chain, "chainKey" | "nodes">[], { textWriterIDs = [] }: { textWriterIDs?: string[] } = {}): void {
340
+ if (this._freed) {
341
+ console.warn("CircleLineChainPlugin is freed, cannot update coordinates.");
342
+ return;
343
+ }
344
+
345
+ const chainKeys = [];
346
+
347
+ for (const chain of chains) {
348
+ const { chainKey, nodes } = chain;
349
+ chainKeys.push(chainKey);
350
+ nodes.forEach((node, index) => {
351
+ this._chainListMap.updateCoordsinatesOfNode(node, chainKey);
352
+
353
+ });
354
+ }
355
+ this._updateTexts(chainKeys, textWriterIDs);
356
+ this._reconstructChains(chainKeys);
357
+ }
358
+
359
+
360
+ updateNodeCoordinates(
361
+ node: Pick<Node, "key" | "lat" | "long">,
362
+ chainKey: string,
363
+ { textWriterIDs = [] }: { textWriterIDs?: string[] } = {}
364
+ ) {
365
+ if (this._freed) {
366
+ console.warn("CircleLineChainPlugin is freed, cannot update node coordinates.");
367
+ return;
368
+ }
369
+
370
+ this._chainListMap.updateCoordsinatesOfNode(node, chainKey);
371
+ if (textWriterIDs && textWriterIDs.length > 0) {
372
+ this._updateTexts([chainKey], textWriterIDs);
373
+ }
374
+ this._reconstructChains([chainKey]);
375
+ this.globe?.DrawRender();
376
+ }
377
+
378
+
379
+ updateChainProperties(chainKey: string, properties: Map<string, any>): void {
380
+ if (this._freed) {
381
+ console.warn("CircleLineChainPlugin is freed, cannot update chain properties.");
382
+ return;
383
+ }
384
+ this._chainListMap.updateChainProperties(chainKey, properties);
385
+
386
+ this._cleanChainsFromSemiPlugins([chainKey]);
387
+ this._reconstructChains([chainKey]);
388
+ this._updateTexts([chainKey], Array.from(this._textWritersMap.keys()));
389
+ this.globe?.DrawRender();
390
+ }
391
+
392
+ updateText(textWriterIDs: string[], chainKeys: string[] | null = null): void {
393
+ if (this._freed) {
394
+ console.warn("CircleLineChainPlugin is freed, cannot update text.");
395
+ return;
396
+ }
397
+ if (!chainKeys) {
398
+ chainKeys = Array.from(this._chainListMap.getAllChainKeysIterator());
399
+ }
400
+ this._updateTexts(chainKeys, textWriterIDs);
401
+ this.globe?.DrawRender();
402
+ }
403
+
404
+
405
+ setDefaultSemiPluginColor(
406
+ semiPluginName: "circleOnTerrain" | "arcOnTerrain" | "line" | "ALL",
407
+ color: Color
408
+ ) {
409
+
410
+ if (semiPluginName === "ALL") {
411
+ this._semiPluginOptions.circleOnTerrainOptions.defaultColor = color;
412
+ this._semiPluginOptions.arcOnTerrainOptions.defaultColor = color;
413
+ this._semiPluginOptions.lineOptions.defaultColor = color;
414
+ this.circlePlugin?.setDefaultColor(color);
415
+ this.arcPlugin?.setDefaultColor(color);
416
+ this.linePlugin?.setDefaultColor(color);
417
+ return;
418
+ }
419
+ switch (semiPluginName) {
420
+ case "circleOnTerrain":
421
+ this._semiPluginOptions.circleOnTerrainOptions.defaultColor = color;
422
+ this.circlePlugin?.setDefaultColor(color);
423
+ break;
424
+ case "arcOnTerrain":
425
+ this._semiPluginOptions.arcOnTerrainOptions.defaultColor = color;
426
+ this.arcPlugin?.setDefaultColor(color);
427
+ break;
428
+ case "line":
429
+ this._semiPluginOptions.lineOptions.defaultColor = color;
430
+ this.linePlugin?.setDefaultColor(color);
431
+ break;
432
+ default:
433
+ throw new Error(`Unknown semi-plugin name: ${semiPluginName}`);
434
+ }
435
+ }
436
+ // IMPLICIT METHODS
437
+
438
+
439
+ _checktextWritersMap(textWritersMap: Map<string, ContextTextWriter3>): void {
440
+ if (!(textWritersMap instanceof Map)) throw new Error("textWritersMap is not an instance of Map");
441
+ textWritersMap.forEach((v) => {
442
+ if (!(v instanceof ContextTextWriter3)) throw new Error("textWritersMap element is not an instance of ContextTextWriter3");
443
+ });
444
+ }
445
+
446
+
447
+ _updateTexts(chainKeys: string[], textWriterIDs: string[]): void {
448
+ if (textWriterIDs.length === 0) return;
449
+ const textWriters = textWriterGetOrThrow(this._textWritersMap, textWriterIDs)
450
+ chainKeys.forEach((chainKey) => {
451
+ this._chainListMap.textUpdate(chainKey, textWriters, this._textDataPreAdaptor);
452
+ });
453
+ }
454
+
455
+
456
+
457
+
458
+ _cleanChainsFromSemiPlugins(chainKeys: string[]): void {
459
+ if (!this.globe || !this.gl) {
460
+ throw new Error("Globe or WebGL context is not initialized");
461
+ }
462
+
463
+ for (const chainKey of chainKeys) {
464
+ // Clean chains from text writers
465
+ const nodeKeys = this._chainListMap.getNodeKeysOfChain(chainKey);
466
+ this._textWritersMap.forEach((writer) => {
467
+ writer.deleteTextBulk(nodeKeys);
468
+ });
469
+ nodeKeys.pop(); // Remove the last key which is destination of the last circle
470
+ // Clean chains from semi-plugins
471
+ this.circlePlugin?.deleteBulk(nodeKeys);
472
+ this.linePlugin?.deleteBulk(nodeKeys);
473
+ this.arcPlugin?.deleteBulk(nodeKeys);
474
+ }
475
+ }
476
+
477
+
478
+
479
+ _reconstructChains(chainKeys: string[]): void {
480
+ // TODO: this is core
481
+ // Get chain nodes
482
+ const globe = this.globe as Globe;
483
+ if (!globe || !this.gl) {
484
+ throw new Error("Globe or WebGL context is not initialized");
485
+ }
486
+ for (let chainKey of chainKeys) {
487
+ const chain = this._chainListMap.getChain(chainKey);
488
+ if (!chain) {
489
+ console.warn(`Chain with key ${chainKey} not found.`);
490
+ continue;
491
+ }
492
+ const lineInput = lineDataAdaptor(chain);
493
+ const arcInput = arcDataAdaptor(chain);
494
+ const circleInput = circleDataAdaptor(globe, chain);
495
+ this.linePlugin?.insertBulk(lineInput);
496
+ this.arcPlugin?.insertBulk(arcInput);
497
+ this.circlePlugin?.insertBulk(circleInput);
498
+
499
+ }
500
+ }
501
+
502
+
503
+
504
+
505
+ // GLOBE INTERFACE METHODS
506
+
507
+ init(globe: Globe, gl: WebGL2RenderingContext): void {
508
+ this.globe = globe;
509
+ this.gl = gl;
510
+
511
+ // Initialize sub-plugins with unique IDs
512
+ this.circlePlugin = new CircleOnTerrainPlugin(`${this.id}_unregistered_circles`,
513
+ this._semiPluginOptions.circleOnTerrainOptions);
514
+ this.linePlugin = new LinePlugin(`${this.id}_unregistered_lines`,
515
+ this._semiPluginOptions.lineOptions);
516
+ this.arcPlugin = new ArcOnTerrainPlugin(`${this.id}_unregistered_arcs`,
517
+ this._semiPluginOptions.arcOnTerrainOptions);
518
+ this.circlePlugin.init(globe, gl);
519
+ this.linePlugin.init(globe, gl);
520
+ this.arcPlugin.init(globe, gl);
521
+
522
+ }
523
+
524
+
525
+ draw3D(): void {
526
+ if (this._freed) {
527
+ console.warn("CircleLineChainPlugin is freed, cannot draw.");
528
+ return;
529
+ }
530
+ const { globe, gl } = this;
531
+ if (!globe || !gl) {
532
+ console.warn("Globe or WebGL context is not initialized, cannot draw.");
533
+ return;
534
+ }
535
+
536
+ const circleOpacity = getOpacity(this._opacities, "circle");
537
+ if (this._drawCircleOn && circleOpacity !== 0) {
538
+ this.circlePlugin?.setPluginOpacity(circleOpacity, false);
539
+ this.circlePlugin?.draw3D();
540
+ }
541
+
542
+ const currentGeometry = globe.api_GetCurrentGeometry();
543
+
544
+ switch (currentGeometry) {
545
+ case 0: {
546
+ // globe view
547
+
548
+ const lineOpacity = getOpacity(this._opacities, "globeArc");
549
+ if (lineOpacity !== 0) {
550
+ this.linePlugin?.setPluginOpacity(lineOpacity, false);
551
+ this.linePlugin?.draw3D();
552
+ }
553
+ const arcOpacity = getOpacity(this._opacities, "globeArcFitsTerrain");
554
+ if (arcOpacity !== 0) {
555
+ this.arcPlugin?.setPluginOpacity(arcOpacity, false);
556
+ this.arcPlugin?.draw3D();
557
+ }
558
+ break;
559
+ }
560
+ case 1: {
561
+ // flat view
562
+ const lineOpacity = getOpacity(this._opacities, "flatStraightLine");
563
+ if (lineOpacity !== 0) {
564
+ this.linePlugin?.setPluginOpacity(lineOpacity);
565
+ this.linePlugin?.draw3D();
566
+ }
567
+ const arcOpacity = getOpacity(this._opacities, "flatGreatCircleLine");
568
+ if (arcOpacity !== 0) {
569
+ this.arcPlugin?.setPluginOpacity(arcOpacity);
570
+ this.arcPlugin?.draw3D();
571
+ }
572
+ break;
573
+ }
574
+ default: {
575
+ throw new Error("Unknown geometry type, Implementation need on Circle-Line-Chain Plugin");
576
+ }
577
+ }
578
+
579
+ this._textWritersMap.forEach((writer) => {
580
+ writer.draw();
581
+ });
582
+ }
583
+
584
+
585
+ free(): void {
586
+ if (this._freed) return;
587
+ this._freed = true;
588
+
589
+ // Free sub-plugins
590
+ this.circlePlugin?.free();
591
+ this.linePlugin?.free();
592
+ this.arcPlugin?.free();
593
+
594
+
595
+ // Clear text writers map
596
+ this._textWritersMap.clear();
597
+
598
+ // Clear references
599
+ this.globe = null;
600
+ this.gl = null;
601
+ this.circlePlugin = null;
602
+ this.linePlugin = null;
603
+ this.arcPlugin = null;
604
+ }
605
+
606
+
607
+ }