@pirireis/webglobeplugins 1.0.2 → 1.0.3

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 (259) hide show
  1. package/Math/{angle-calculation.ts → angle-calculation.js} +14 -18
  2. package/Math/{arc-cdf-points.ts → arc-cdf-points.js} +272 -329
  3. package/Math/{arc-generate-points-exponantial.ts → arc-generate-points-exponantial.js} +254 -299
  4. package/Math/{arc.ts → arc.js} +292 -421
  5. package/Math/bounds/line-bbox.js +186 -225
  6. package/Math/{circle-cdf-points.ts → circle-cdf-points.js} +78 -143
  7. package/Math/{circle.ts → circle.js} +33 -49
  8. package/Math/{constants.ts → constants.js} +4 -12
  9. package/Math/contour/{quadtreecontours.ts → quadtreecontours.js} +300 -371
  10. package/Math/contour/quadtreecontours1.js +298 -336
  11. package/Math/{finite-line-2d.ts → finite-line-2d.js} +58 -68
  12. package/Math/{haversine.ts → haversine.js} +22 -33
  13. package/Math/index.js +1 -0
  14. package/Math/juction/{arc-plane.ts → arc-plane.js} +143 -203
  15. package/Math/juction/{line-sphere.ts → line-sphere.js} +22 -32
  16. package/Math/juction/{plane-plane.ts → plane-plane.js} +53 -62
  17. package/Math/{line.ts → line.js} +52 -84
  18. package/Math/matrix4.js +1 -0
  19. package/Math/{methods.ts → methods.js} +126 -182
  20. package/Math/{plane.ts → plane.js} +56 -92
  21. package/Math/{quaternion.ts → quaternion.js} +106 -128
  22. package/Math/templete-shapes/{grid-visually-equal.ts → grid-visually-equal.js} +65 -118
  23. package/Math/tessellation/constants.js +1 -0
  24. package/Math/tessellation/{methods.ts → methods.js} +49 -79
  25. package/Math/tessellation/{nearest-value-padding.ts → nearest-value-padding.js} +112 -147
  26. package/Math/tessellation/{spherical-triangle-area.ts → spherical-triangle-area.js} +99 -127
  27. package/Math/tessellation/{tile-merger.ts → tile-merger.js} +429 -578
  28. package/Math/tessellation/{triangle-tessellation.ts → triangle-tessellation.js} +386 -533
  29. package/Math/tessellation/types.js +1 -0
  30. package/Math/types.js +1 -0
  31. package/Math/utils.js +2 -3
  32. package/Math/{vec3.ts → vec3.js} +155 -227
  33. package/Math/{xyz-tile.ts → xyz-tile.js} +18 -26
  34. package/algorithms/search-binary.js +16 -14
  35. package/altitude-locator/adaptors.js +1 -0
  36. package/altitude-locator/keymethod.js +1 -0
  37. package/altitude-locator/plugin.js +344 -445
  38. package/altitude-locator/types.js +21 -26
  39. package/compass-rose/compass-rose-padding-flat.js +230 -274
  40. package/compass-rose/{compass-text-writer.ts → compass-text-writer.js} +155 -210
  41. package/compass-rose/index.js +3 -3
  42. package/{constants.ts → constants.js} +6 -8
  43. package/heatwave/datamanager.js +149 -168
  44. package/heatwave/heatwave.js +206 -261
  45. package/heatwave/index.js +5 -5
  46. package/heatwave/isobar.js +303 -340
  47. package/heatwave/{texture-point-sampler.ts → texture-point-sampler.js} +187 -220
  48. package/investigation-tools/draw/tiles/adapters.js +67 -0
  49. package/investigation-tools/draw/tiles/{tiles.ts → tiles.js} +128 -162
  50. package/jest.config.js +7 -6
  51. package/package.json +1 -1
  52. package/pin/pin-object-array1.js +300 -381
  53. package/pin/pin-point-totem1.js +60 -77
  54. package/programs/arrowfield/arrow-field.js +60 -89
  55. package/programs/arrowfield/logic.js +141 -173
  56. package/programs/data2legend/density-to-legend.js +68 -86
  57. package/programs/data2legend/point-to-density-texture.js +67 -84
  58. package/programs/float2legendwithratio/index.js +2 -3
  59. package/programs/float2legendwithratio/logic.js +118 -144
  60. package/programs/float2legendwithratio/object.js +104 -141
  61. package/programs/helpers/blender.js +58 -73
  62. package/programs/helpers/{fadeaway.ts → fadeaway.js} +60 -73
  63. package/programs/index.js +20 -19
  64. package/programs/line-on-globe/circle-accurate-3d.js +85 -112
  65. package/programs/line-on-globe/circle-accurate-flat.js +148 -200
  66. package/programs/line-on-globe/degree-padding-around-circle-3d.js +102 -134
  67. package/programs/line-on-globe/index.js +1 -0
  68. package/programs/line-on-globe/lines-color-instanced-flat.js +80 -99
  69. package/programs/line-on-globe/linestrip/data.js +4 -0
  70. package/programs/line-on-globe/linestrip/{linestrip.ts → linestrip.js} +93 -152
  71. package/programs/line-on-globe/{naive-accurate-flexible.ts → naive-accurate-flexible.js} +126 -175
  72. package/programs/line-on-globe/util.js +5 -8
  73. package/programs/picking/pickable-polygon-renderer.js +98 -129
  74. package/programs/picking/pickable-renderer.js +98 -130
  75. package/programs/point-on-globe/element-globe-surface-glow.js +93 -122
  76. package/programs/point-on-globe/element-point-glow.js +80 -114
  77. package/programs/point-on-globe/square-pixel-point.js +121 -139
  78. package/programs/polygon-on-globe/{texture-dem-triangles.ts → texture-dem-triangles.js} +163 -207
  79. package/programs/{programcache.ts → programcache.js} +126 -134
  80. package/programs/rings/index.js +1 -1
  81. package/programs/rings/partial-ring/{piece-of-pie.ts → piece-of-pie.js} +152 -222
  82. package/programs/totems/camera-totem-attactment-interface.js +1 -0
  83. package/programs/totems/{camerauniformblock.ts → camerauniformblock.js} +225 -310
  84. package/programs/totems/{canvas-webglobe-info.ts → canvas-webglobe-info.js} +132 -147
  85. package/programs/totems/{dem-textures-manager.ts → dem-textures-manager.js} +257 -360
  86. package/programs/totems/{globe-changes.ts → globe-changes.js} +59 -79
  87. package/programs/totems/gpu-selection-uniform-block.js +99 -127
  88. package/programs/totems/{index.ts → index.js} +2 -2
  89. package/programs/two-d/pixel-padding-for-compass.js +87 -101
  90. package/programs/util.js +14 -19
  91. package/programs/vectorfields/logics/{constants.ts → constants.js} +4 -5
  92. package/programs/vectorfields/logics/{drawrectangleparticles.ts → drawrectangleparticles.js} +80 -115
  93. package/programs/vectorfields/logics/index.js +2 -4
  94. package/programs/vectorfields/logics/particle-ubo.js +16 -0
  95. package/programs/vectorfields/logics/{pixelbased.ts → pixelbased.js} +86 -115
  96. package/programs/vectorfields/logics/ubo.js +51 -57
  97. package/programs/vectorfields/{pingpongbuffermanager.ts → pingpongbuffermanager.js} +99 -113
  98. package/range-tools-on-terrain/bearing-line/{adapters.ts → adapters.js} +114 -154
  99. package/range-tools-on-terrain/bearing-line/{plugin.ts → plugin.js} +457 -569
  100. package/range-tools-on-terrain/bearing-line/types.js +1 -0
  101. package/range-tools-on-terrain/circle-line-chain/{adapters.ts → adapters.js} +85 -104
  102. package/range-tools-on-terrain/circle-line-chain/{chain-list-map.ts → chain-list-map.js} +382 -446
  103. package/range-tools-on-terrain/circle-line-chain/{plugin.ts → plugin.js} +464 -607
  104. package/range-tools-on-terrain/circle-line-chain/types.js +1 -0
  105. package/range-tools-on-terrain/range-ring/{adapters.ts → adapters.js} +93 -114
  106. package/range-tools-on-terrain/range-ring/{enum.ts → enum.js} +2 -2
  107. package/range-tools-on-terrain/range-ring/{plugin.ts → plugin.js} +377 -444
  108. package/range-tools-on-terrain/range-ring/rangeringangletext.js +331 -0
  109. package/range-tools-on-terrain/range-ring/types.js +9 -0
  110. package/semiplugins/interface.js +1 -0
  111. package/semiplugins/lightweight/{line-plugin.ts → line-plugin.js} +221 -342
  112. package/semiplugins/lightweight/{piece-of-pie-plugin.ts → piece-of-pie-plugin.js} +200 -275
  113. package/semiplugins/shape-on-terrain/{arc-plugin.ts → arc-plugin.js} +481 -616
  114. package/semiplugins/shape-on-terrain/{circle-plugin.ts → circle-plugin.js} +444 -588
  115. package/semiplugins/shape-on-terrain/{padding-1-degree.ts → padding-1-degree.js} +539 -713
  116. package/semiplugins/shape-on-terrain/terrain-polygon/{adapters.ts → adapters.js} +55 -69
  117. package/semiplugins/shape-on-terrain/terrain-polygon/data/{cache.ts → cache.js} +102 -149
  118. package/semiplugins/shape-on-terrain/terrain-polygon/data/{index-polygon-map.ts → index-polygon-map.js} +45 -58
  119. package/semiplugins/shape-on-terrain/terrain-polygon/data/{manager.ts → manager.js} +4 -4
  120. package/semiplugins/shape-on-terrain/terrain-polygon/data/master-worker.js +177 -196
  121. package/semiplugins/shape-on-terrain/terrain-polygon/data/{polygon-to-triangles.ts → polygon-to-triangles.js} +100 -144
  122. package/semiplugins/shape-on-terrain/terrain-polygon/data/{random.ts → random.js} +121 -165
  123. package/semiplugins/shape-on-terrain/terrain-polygon/data/types.js +1 -0
  124. package/semiplugins/shape-on-terrain/terrain-polygon/data/{worker-contact.ts → worker-contact.js} +63 -81
  125. package/semiplugins/shape-on-terrain/terrain-polygon/data/worker.js +125 -146
  126. package/semiplugins/shape-on-terrain/terrain-polygon/{terrain-polygon.ts → terrain-polygon.js} +219 -265
  127. package/semiplugins/shape-on-terrain/terrain-polygon/types.js +8 -0
  128. package/semiplugins/shell/bbox-renderer/index.js +2 -0
  129. package/semiplugins/shell/bbox-renderer/{logic.ts → logic.js} +209 -273
  130. package/semiplugins/shell/bbox-renderer/object.js +75 -0
  131. package/semiplugins/type.js +1 -0
  132. package/semiplugins/utility/{container-plugin.ts → container-plugin.js} +94 -126
  133. package/semiplugins/utility/{object-pass-container-plugin.ts → object-pass-container-plugin.js} +80 -101
  134. package/shaders/fragment-toy/firework.js +1 -1
  135. package/shaders/fragment-toy/singularity.js +2 -5
  136. package/tracks/point-heat-map/adaptors/timetracksplugin-format-to-this.js +63 -78
  137. package/tracks/point-heat-map/index.js +1 -0
  138. package/tracks/point-heat-map/plugin-webworker.js +121 -148
  139. package/tracks/point-heat-map/point-to-heat-map-flow.js +121 -150
  140. package/tracks/point-tracks/key-methods.js +2 -3
  141. package/tracks/point-tracks/plugin.js +401 -487
  142. package/tracks/timetracks/adaptors-line-strip.js +65 -79
  143. package/tracks/timetracks/plugin-line-strip.js +240 -295
  144. package/tracks/timetracks/program-line-strip.js +411 -495
  145. package/tracks/timetracks/programpoint-line-strip.js +109 -137
  146. package/types.js +19 -0
  147. package/util/account/bufferoffsetmanager.js +176 -209
  148. package/util/account/create-buffermap-orchastration.js +39 -0
  149. package/util/account/index.js +3 -6
  150. package/util/account/single-attribute-buffer-management/{buffer-manager.ts → buffer-manager.js} +119 -151
  151. package/util/account/single-attribute-buffer-management/{buffer-orchestrator.ts → buffer-orchestrator.js} +212 -238
  152. package/util/account/single-attribute-buffer-management/{buffer-orchestrator1.ts → buffer-orchestrator1.js} +159 -184
  153. package/util/account/single-attribute-buffer-management/{index.ts → index.js} +4 -11
  154. package/util/account/single-attribute-buffer-management/{object-store.ts → object-store.js} +55 -76
  155. package/util/account/single-attribute-buffer-management/types.js +1 -0
  156. package/util/account/util.js +18 -22
  157. package/util/algorithms/index.js +1 -0
  158. package/util/algorithms/search-binary.js +25 -26
  159. package/util/build-strategy/{static-dynamic.ts → static-dynamic.js} +41 -50
  160. package/util/check/index.js +1 -0
  161. package/util/check/typecheck.js +66 -0
  162. package/util/{frame-counter-trigger.ts → frame-counter-trigger.js} +84 -99
  163. package/util/geometry/{index.ts → index.js} +121 -155
  164. package/util/gl-util/buffer/{attribute-loader.ts → attribute-loader.js} +62 -84
  165. package/util/gl-util/buffer/{index.ts → index.js} +3 -6
  166. package/util/gl-util/draw-options/{methods.ts → methods.js} +32 -47
  167. package/util/gl-util/uniform-block/{manager.ts → manager.js} +200 -232
  168. package/util/{globe-default-gl-states.ts → globe-default-gl-states.js} +4 -5
  169. package/util/{helper-methods.ts → helper-methods.js} +8 -9
  170. package/util/index.js +10 -9
  171. package/util/interpolation/index.js +1 -0
  172. package/util/interpolation/timetrack/index.js +2 -9
  173. package/util/interpolation/timetrack/timetrack-interpolator.js +79 -94
  174. package/util/interpolation/timetrack/web-worker.js +46 -51
  175. package/util/picking/{fence.ts → fence.js} +43 -47
  176. package/util/picking/{picker-displayer.ts → picker-displayer.js} +176 -226
  177. package/util/programs/draw-from-pixel-coords.js +164 -201
  178. package/util/programs/{draw-texture-on-canvas.ts → draw-texture-on-canvas.js} +69 -91
  179. package/util/programs/supersampletotextures.js +97 -130
  180. package/util/programs/texturetoglobe.js +128 -153
  181. package/util/shaderfunctions/{geometrytransformations.ts → geometrytransformations.js} +44 -106
  182. package/util/shaderfunctions/index.js +2 -2
  183. package/util/shaderfunctions/nodata.js +2 -4
  184. package/util/shaderfunctions/noisefunctions.js +7 -10
  185. package/util/{webglobjectbuilders.ts → webglobjectbuilders.js} +358 -446
  186. package/vectorfield/arrowfield/adaptor.js +11 -11
  187. package/vectorfield/arrowfield/index.js +3 -3
  188. package/vectorfield/arrowfield/plugin.js +83 -128
  189. package/vectorfield/waveparticles/adaptor.js +15 -16
  190. package/vectorfield/waveparticles/index.js +3 -3
  191. package/vectorfield/waveparticles/{plugin.ts → plugin.js} +415 -506
  192. package/vectorfield/wind/adapters/{image-to-fields.ts → image-to-fields.js} +61 -74
  193. package/vectorfield/wind/adapters/types.js +1 -0
  194. package/vectorfield/wind/{imagetovectorfieldandmagnitude.ts → imagetovectorfieldandmagnitude.js} +53 -78
  195. package/vectorfield/wind/index.js +5 -5
  196. package/vectorfield/wind/{plugin-persistant copy.ts → plugin-persistant copy.js } +364 -461
  197. package/vectorfield/wind/{plugin-persistant.ts → plugin-persistant.js} +375 -483
  198. package/vectorfield/wind/plugin.js +685 -883
  199. package/vectorfield/wind/vectorfieldimage.js +23 -27
  200. package/write-text/{context-text-bulk.ts → context-text-bulk.js} +200 -285
  201. package/write-text/context-text3.js +167 -0
  202. package/write-text/{context-text4.ts → context-text4.js} +146 -231
  203. package/write-text/context-textDELETE.js +94 -125
  204. package/write-text/objectarraylabels/{index.ts → index.js} +2 -2
  205. package/write-text/objectarraylabels/objectarraylabels.js +200 -247
  206. package/Math/matrix4.ts +0 -0
  207. package/Math/mesh/mapbox-delaunay.d.ts +0 -74
  208. package/Math/roadmap.md +0 -10
  209. package/Math/tessellation/constants.ts +0 -1
  210. package/Math/tessellation/roadmap.md +0 -48
  211. package/Math/tessellation/types.ts +0 -1
  212. package/Math/types.ts +0 -68
  213. package/investigation-tools/draw/tiles/adapters.ts +0 -133
  214. package/programs/line-on-globe/linestrip/data.ts +0 -29
  215. package/programs/polygon-on-globe/roadmap.md +0 -8
  216. package/programs/totems/camera-totem-attactment-interface.ts +0 -4
  217. package/programs/vectorfields/logics/particle-ubo.ts +0 -23
  218. package/publish.bat +0 -62
  219. package/range-tools-on-terrain/bearing-line/types.ts +0 -65
  220. package/range-tools-on-terrain/circle-line-chain/types.ts +0 -43
  221. package/range-tools-on-terrain/range-ring/rangeringangletext.ts +0 -396
  222. package/range-tools-on-terrain/range-ring/types.ts +0 -30
  223. package/semiplugins/interface.ts +0 -14
  224. package/semiplugins/shape-on-terrain/goal.md +0 -12
  225. package/semiplugins/shape-on-terrain/terrain-polygon/data/cache-shortcuts.md +0 -20
  226. package/semiplugins/shape-on-terrain/terrain-polygon/data/master-worker.ts +0 -209
  227. package/semiplugins/shape-on-terrain/terrain-polygon/data/readme.md +0 -5
  228. package/semiplugins/shape-on-terrain/terrain-polygon/data/types.ts +0 -37
  229. package/semiplugins/shape-on-terrain/terrain-polygon/notes.md +0 -90
  230. package/semiplugins/shape-on-terrain/terrain-polygon/types.ts +0 -69
  231. package/semiplugins/shell/bbox-renderer/index.ts +0 -2
  232. package/semiplugins/shell/bbox-renderer/object.ts +0 -129
  233. package/semiplugins/type.ts +0 -8
  234. package/terrain-plugin.mmd +0 -83
  235. package/tests/Math/arc-sampling-test.js +0 -367
  236. package/tests/Math/arc-sampling-test.ts +0 -429
  237. package/tests/Math/arc.test.ts +0 -77
  238. package/tests/Math/junction/arc-limit.test.ts +0 -7
  239. package/tests/Math/junction/arc-plane-points.test.ts +0 -196
  240. package/tests/Math/junction/arc-plane.test.ts +0 -172
  241. package/tests/Math/junction/line-sphere.test.ts +0 -127
  242. package/tests/Math/junction/plane-plane.test.ts +0 -91
  243. package/tests/Math/plane-test.ts +0 -17
  244. package/tests/Math/plane.test.ts +0 -43
  245. package/tests/Math/vec3.test.ts +0 -33
  246. package/tracks/point-heat-map/readme.md +0 -15
  247. package/tracks/timetracks/readme.md +0 -1
  248. package/tsconfig.json +0 -22
  249. package/types/@pirireis/webglobe.d.ts +0 -102
  250. package/types/delaunator.d.ts +0 -40
  251. package/types/earcut.d.ts +0 -11
  252. package/types/rbush.d.ts +0 -57
  253. package/types.ts +0 -319
  254. package/util/account/create-buffermap-orchastration.ts +0 -85
  255. package/util/account/single-attribute-buffer-management/types.ts +0 -43
  256. package/util/check/typecheck.ts +0 -74
  257. package/vectorfield/wind/adapters/types.ts +0 -12
  258. package/write-text/context-text3.ts +0 -252
  259. package/write-text/objectarraylabels/objectarraylabels.d.ts +0 -72
@@ -1,607 +1,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
- }
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
+ }