@armyc2.c5isr.renderer/mil-sym-ts-web 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +57 -0
  3. package/buildNode.bat +2 -0
  4. package/buildWeb.bat +2 -0
  5. package/dist/C5Ren.d.ts +6970 -0
  6. package/dist/C5Ren.js +2 -0
  7. package/dist/C5Ren.js.map +1 -0
  8. package/dist/LICENSE +201 -0
  9. package/dist/README.md +57 -0
  10. package/dist/armyc2.c5isr.renderer-mil-sym-ts-web-2.2.0.tgz +0 -0
  11. package/dist/manifest.json +4 -0
  12. package/dist/package.json +16 -0
  13. package/index.ts +169 -0
  14. package/package.bak +50 -0
  15. package/package.json +40 -0
  16. package/package.node.json +43 -0
  17. package/package.pack.json +19 -0
  18. package/package.packWeb.json +16 -0
  19. package/package.web.json +40 -0
  20. package/src/main/ts/android/graphics/Bitmap.ts +7 -0
  21. package/src/main/ts/android/graphics/Paint.ts +26 -0
  22. package/src/main/ts/android/graphics/Path.ts +78 -0
  23. package/src/main/ts/android/graphics/PointF.ts +14 -0
  24. package/src/main/ts/android/graphics/Rect.ts +18 -0
  25. package/src/main/ts/android/graphics/RectF.ts +50 -0
  26. package/src/main/ts/android/graphics/Region.ts +36 -0
  27. package/src/main/ts/android/graphics/Typeface.ts +11 -0
  28. package/src/main/ts/armyc2/c5isr/JavaLineArray/BasicShapes.ts +99 -0
  29. package/src/main/ts/armyc2/c5isr/JavaLineArray/CChannelPoints2.ts +34 -0
  30. package/src/main/ts/armyc2/c5isr/JavaLineArray/CELineArray.ts +193 -0
  31. package/src/main/ts/armyc2/c5isr/JavaLineArray/Channels.ts +2971 -0
  32. package/src/main/ts/armyc2/c5isr/JavaLineArray/DISMSupport.ts +4008 -0
  33. package/src/main/ts/armyc2/c5isr/JavaLineArray/POINT2.ts +93 -0
  34. package/src/main/ts/armyc2/c5isr/JavaLineArray/Shape2.ts +89 -0
  35. package/src/main/ts/armyc2/c5isr/JavaLineArray/TacticalLines.ts +515 -0
  36. package/src/main/ts/armyc2/c5isr/JavaLineArray/arraysupport.ts +5403 -0
  37. package/src/main/ts/armyc2/c5isr/JavaLineArray/countsupport.ts +1084 -0
  38. package/src/main/ts/armyc2/c5isr/JavaLineArray/flot.ts +2173 -0
  39. package/src/main/ts/armyc2/c5isr/JavaLineArray/lineutility.ts +4934 -0
  40. package/src/main/ts/armyc2/c5isr/JavaLineArray/ref.ts +7 -0
  41. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/Modifier2.ts +5601 -0
  42. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/P1.ts +14 -0
  43. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/TGLight.ts +648 -0
  44. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/clsChannelUtility.ts +647 -0
  45. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/clsMETOC.ts +2994 -0
  46. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/clsUtility.ts +2663 -0
  47. package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/mdlGeodesic.ts +669 -0
  48. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsClipPolygon2.ts +971 -0
  49. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsClipQuad.ts +871 -0
  50. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsRenderer.ts +3507 -0
  51. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsRenderer2.ts +500 -0
  52. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsUtility.ts +1089 -0
  53. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsUtilityCPOF.ts +2656 -0
  54. package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsUtilityGE.ts +1419 -0
  55. package/src/main/ts/armyc2/c5isr/data/genc.json +1407 -0
  56. package/src/main/ts/armyc2/c5isr/data/msd.json +17311 -0
  57. package/src/main/ts/armyc2/c5isr/data/mse.json +18500 -0
  58. package/src/main/ts/armyc2/c5isr/data/svgd.json +31214 -0
  59. package/src/main/ts/armyc2/c5isr/data/svge.json +30558 -0
  60. package/src/main/ts/armyc2/c5isr/graphics2d/AffineTransform.ts +10 -0
  61. package/src/main/ts/armyc2/c5isr/graphics2d/Area.ts +437 -0
  62. package/src/main/ts/armyc2/c5isr/graphics2d/BasicStroke.ts +429 -0
  63. package/src/main/ts/armyc2/c5isr/graphics2d/BasicTypes.ts +7 -0
  64. package/src/main/ts/armyc2/c5isr/graphics2d/BufferedImage.ts +35 -0
  65. package/src/main/ts/armyc2/c5isr/graphics2d/Font.ts +111 -0
  66. package/src/main/ts/armyc2/c5isr/graphics2d/FontMetrics.ts +29 -0
  67. package/src/main/ts/armyc2/c5isr/graphics2d/FontRenderContext.ts +18 -0
  68. package/src/main/ts/armyc2/c5isr/graphics2d/GeneralPath.ts +211 -0
  69. package/src/main/ts/armyc2/c5isr/graphics2d/Graphics2D.ts +80 -0
  70. package/src/main/ts/armyc2/c5isr/graphics2d/IPathIterator.ts +33 -0
  71. package/src/main/ts/armyc2/c5isr/graphics2d/ImageIO.ts +16 -0
  72. package/src/main/ts/armyc2/c5isr/graphics2d/Line2D.ts +726 -0
  73. package/src/main/ts/armyc2/c5isr/graphics2d/PathIterator.ts +141 -0
  74. package/src/main/ts/armyc2/c5isr/graphics2d/Point.ts +112 -0
  75. package/src/main/ts/armyc2/c5isr/graphics2d/Point2D.ts +261 -0
  76. package/src/main/ts/armyc2/c5isr/graphics2d/Polygon.ts +391 -0
  77. package/src/main/ts/armyc2/c5isr/graphics2d/Rectangle.ts +567 -0
  78. package/src/main/ts/armyc2/c5isr/graphics2d/Rectangle2D.ts +445 -0
  79. package/src/main/ts/armyc2/c5isr/graphics2d/Shape.ts +31 -0
  80. package/src/main/ts/armyc2/c5isr/graphics2d/Stroke.ts +18 -0
  81. package/src/main/ts/armyc2/c5isr/graphics2d/TextLayout.ts +45 -0
  82. package/src/main/ts/armyc2/c5isr/graphics2d/TexturePaint.ts +25 -0
  83. package/src/main/ts/armyc2/c5isr/renderer/IIconRenderer.ts +15 -0
  84. package/src/main/ts/armyc2/c5isr/renderer/IconRenderer.ts +22 -0
  85. package/src/main/ts/armyc2/c5isr/renderer/MilStdIconRenderer.ts +269 -0
  86. package/src/main/ts/armyc2/c5isr/renderer/ModifierRenderer.ts +9882 -0
  87. package/src/main/ts/armyc2/c5isr/renderer/PatternFillRenderer.ts +146 -0
  88. package/src/main/ts/armyc2/c5isr/renderer/SinglePointSVGRenderer.ts +1265 -0
  89. package/src/main/ts/armyc2/c5isr/renderer/shapes/arc.ts +64 -0
  90. package/src/main/ts/armyc2/c5isr/renderer/shapes/bcurve.ts +95 -0
  91. package/src/main/ts/armyc2/c5isr/renderer/shapes/ellipse.ts +93 -0
  92. package/src/main/ts/armyc2/c5isr/renderer/shapes/line.ts +114 -0
  93. package/src/main/ts/armyc2/c5isr/renderer/shapes/path.ts +555 -0
  94. package/src/main/ts/armyc2/c5isr/renderer/shapes/pathiterator.ts +62 -0
  95. package/src/main/ts/armyc2/c5isr/renderer/shapes/point.ts +120 -0
  96. package/src/main/ts/armyc2/c5isr/renderer/shapes/rectangle.ts +431 -0
  97. package/src/main/ts/armyc2/c5isr/renderer/shapes/roundedrectangle.ts +99 -0
  98. package/src/main/ts/armyc2/c5isr/renderer/shapes/types.ts +25 -0
  99. package/src/main/ts/armyc2/c5isr/renderer/shapes/utilities.ts +203 -0
  100. package/src/main/ts/armyc2/c5isr/renderer/utilities/AffiliationColors.ts +104 -0
  101. package/src/main/ts/armyc2/c5isr/renderer/utilities/Color.ts +481 -0
  102. package/src/main/ts/armyc2/c5isr/renderer/utilities/DistanceUnit.ts +40 -0
  103. package/src/main/ts/armyc2/c5isr/renderer/utilities/DrawRules.ts +1323 -0
  104. package/src/main/ts/armyc2/c5isr/renderer/utilities/EntityCode.ts +51 -0
  105. package/src/main/ts/armyc2/c5isr/renderer/utilities/ErrorLogger.ts +736 -0
  106. package/src/main/ts/armyc2/c5isr/renderer/utilities/GENCLookup.ts +106 -0
  107. package/src/main/ts/armyc2/c5isr/renderer/utilities/GeoPixelConversion3D.ts +84 -0
  108. package/src/main/ts/armyc2/c5isr/renderer/utilities/IMultiPointRenderer.ts +87 -0
  109. package/src/main/ts/armyc2/c5isr/renderer/utilities/IPointConversion.ts +34 -0
  110. package/src/main/ts/armyc2/c5isr/renderer/utilities/ImageInfo.ts +324 -0
  111. package/src/main/ts/armyc2/c5isr/renderer/utilities/LRUCache.ts +127 -0
  112. package/src/main/ts/armyc2/c5isr/renderer/utilities/LRUEntry.ts +18 -0
  113. package/src/main/ts/armyc2/c5isr/renderer/utilities/LogLevel.ts +111 -0
  114. package/src/main/ts/armyc2/c5isr/renderer/utilities/MODrawRules.ts +219 -0
  115. package/src/main/ts/armyc2/c5isr/renderer/utilities/MSInfo.ts +1008 -0
  116. package/src/main/ts/armyc2/c5isr/renderer/utilities/MSLookup.ts +882 -0
  117. package/src/main/ts/armyc2/c5isr/renderer/utilities/MilStdAttributes.ts +380 -0
  118. package/src/main/ts/armyc2/c5isr/renderer/utilities/MilStdSymbol.ts +797 -0
  119. package/src/main/ts/armyc2/c5isr/renderer/utilities/Modifiers.ts +1699 -0
  120. package/src/main/ts/armyc2/c5isr/renderer/utilities/PointConversion.ts +178 -0
  121. package/src/main/ts/armyc2/c5isr/renderer/utilities/PointConversionDummy.ts +45 -0
  122. package/src/main/ts/armyc2/c5isr/renderer/utilities/PointConverter3D.ts +126 -0
  123. package/src/main/ts/armyc2/c5isr/renderer/utilities/RectUtilities.ts +118 -0
  124. package/src/main/ts/armyc2/c5isr/renderer/utilities/RendererException.ts +11 -0
  125. package/src/main/ts/armyc2/c5isr/renderer/utilities/RendererSettings.ts +1201 -0
  126. package/src/main/ts/armyc2/c5isr/renderer/utilities/RendererUtilities.ts +591 -0
  127. package/src/main/ts/armyc2/c5isr/renderer/utilities/SVGInfo.ts +29 -0
  128. package/src/main/ts/armyc2/c5isr/renderer/utilities/SVGLookup.ts +753 -0
  129. package/src/main/ts/armyc2/c5isr/renderer/utilities/SVGSymbolInfo.ts +137 -0
  130. package/src/main/ts/armyc2/c5isr/renderer/utilities/SVGTextInfo.ts +438 -0
  131. package/src/main/ts/armyc2/c5isr/renderer/utilities/SettingsChangedEvent.ts +19 -0
  132. package/src/main/ts/armyc2/c5isr/renderer/utilities/SettingsChangedEventListener.ts +10 -0
  133. package/src/main/ts/armyc2/c5isr/renderer/utilities/SettingsEventListener.ts +5 -0
  134. package/src/main/ts/armyc2/c5isr/renderer/utilities/Shape2SVG.ts +404 -0
  135. package/src/main/ts/armyc2/c5isr/renderer/utilities/ShapeInfo.ts +525 -0
  136. package/src/main/ts/armyc2/c5isr/renderer/utilities/ShapeUtilities.ts +55 -0
  137. package/src/main/ts/armyc2/c5isr/renderer/utilities/SymbolDimensionInfo.ts +36 -0
  138. package/src/main/ts/armyc2/c5isr/renderer/utilities/SymbolID.ts +1055 -0
  139. package/src/main/ts/armyc2/c5isr/renderer/utilities/SymbolUtilities.ts +2085 -0
  140. package/src/main/ts/armyc2/c5isr/renderer/utilities/TextInfo.ts +157 -0
  141. package/src/main/ts/armyc2/c5isr/web/render/GeoPixelConversion.ts +86 -0
  142. package/src/main/ts/armyc2/c5isr/web/render/MultiPointHandler.ts +3798 -0
  143. package/src/main/ts/armyc2/c5isr/web/render/MultiPointHandlerSVG.ts +412 -0
  144. package/src/main/ts/armyc2/c5isr/web/render/PointConverter.ts +124 -0
  145. package/src/main/ts/armyc2/c5isr/web/render/SymbolModifiers.ts +26 -0
  146. package/src/main/ts/armyc2/c5isr/web/render/WebRenderer.ts +677 -0
  147. package/src/main/ts/armyc2/c5isr/web/render/utilities/JavaRendererUtilities.ts +484 -0
  148. package/src/main/ts/armyc2/c5isr/web/render/utilities/LineInfo.ts +62 -0
  149. package/src/main/ts/armyc2/c5isr/web/render/utilities/SymbolInfo.ts +46 -0
  150. package/src/main/ts/armyc2/c5isr/web/render/utilities/TextInfo.ts +51 -0
  151. package/src/main/ts/org/gavaghan/geodesy/Angle.ts +31 -0
  152. package/src/main/ts/org/gavaghan/geodesy/Ellipsoid.ts +71 -0
  153. package/src/main/ts/org/gavaghan/geodesy/GeodeticCalculator.ts +200 -0
  154. package/src/main/ts/org/gavaghan/geodesy/GeodeticCurve.ts +55 -0
  155. package/src/main/ts/org/gavaghan/geodesy/GeodeticMeasurement.ts +68 -0
  156. package/src/main/ts/org/gavaghan/geodesy/GlobalCoordinates.ts +103 -0
  157. package/src/main/ts/org/gavaghan/geodesy/GlobalPosition.ts +90 -0
  158. package/test/ExportSPImages.js +692 -0
  159. package/test/MPWW.html +556 -0
  160. package/test/MPWorker.js +318 -0
  161. package/test/SPWorker.js +233 -0
  162. package/test/SVGWW.html +363 -0
  163. package/test/singlePointTester3.html +751 -0
  164. package/tsconfig.json +54 -0
  165. package/typedoc.json +30 -0
  166. package/updateVersion.js +21 -0
  167. package/webpack.config.js +34 -0
  168. package/webpackn.config.js +28 -0
  169. package/webpackr.config.js +47 -0
  170. package/webpackw.config.js +23 -0
@@ -0,0 +1,1419 @@
1
+ /*
2
+ * A class to create renderables for the ShapeInfo from the GeneralPath
3
+ * This class is used for the GoogleEarth Renderer
4
+ */
5
+ import { Area } from "../graphics2d/Area"
6
+ import { BasicStroke } from "../graphics2d/BasicStroke"
7
+ import { Line2D } from "../graphics2d/Line2D"
8
+ import { PathIterator } from "../graphics2d/PathIterator"
9
+ import { Point2D } from "../graphics2d/Point2D"
10
+ import { Polygon } from "../graphics2d/Polygon"
11
+ import { Rectangle } from "../graphics2d/Rectangle"
12
+ import { Rectangle2D } from "../graphics2d/Rectangle2D"
13
+ import { Shape } from "../graphics2d/Shape"
14
+ import { lineutility } from "../JavaLineArray/lineutility"
15
+ import { POINT2 } from "../JavaLineArray/POINT2"
16
+ import { Shape2 } from "../JavaLineArray/Shape2"
17
+ import { TacticalLines } from "../JavaLineArray/TacticalLines"
18
+ import { clsMETOC } from "../JavaTacticalRenderer/clsMETOC";
19
+ import { clsUtility as clsUtilityJTR } from "../JavaTacticalRenderer/clsUtility";
20
+ import { TGLight } from "../JavaTacticalRenderer/TGLight"
21
+ import { Color } from "../renderer/utilities/Color"
22
+ import { ErrorLogger } from "../renderer/utilities/ErrorLogger"
23
+ import { RendererException } from "../renderer/utilities/RendererException"
24
+ import { ShapeInfo } from "../renderer/utilities/ShapeInfo"
25
+ import { clsUtility } from "./clsUtility";
26
+
27
+ import { type int, type double } from "../../c5isr/graphics2d/BasicTypes";
28
+
29
+ /**
30
+ * Utilities require for GoogleEarth functionality
31
+ *
32
+ */
33
+ export class clsUtilityGE {
34
+ private static readonly _className: string = "clsUtilityGE";
35
+ static setSplineLinetype(tg: TGLight): void {
36
+ switch (tg.get_LineType()) {
37
+ case TacticalLines.BRDGHD: {
38
+ tg.set_LineType(TacticalLines.BRDGHD_GE);
39
+ break;
40
+ }
41
+
42
+ case TacticalLines.HOLD: {
43
+ tg.set_LineType(TacticalLines.HOLD_GE);
44
+ break;
45
+ }
46
+
47
+ case TacticalLines.ICE_OPENINGS_FROZEN: {
48
+ tg.set_LineType(TacticalLines.ICE_OPENINGS_FROZEN_GE);
49
+ break;
50
+ }
51
+
52
+ case TacticalLines.ICE_OPENINGS_LEAD: {
53
+ tg.set_LineType(TacticalLines.ICE_OPENINGS_LEAD_GE);
54
+ break;
55
+ }
56
+
57
+ case TacticalLines.ICE_EDGE_RADAR: {
58
+ tg.set_LineType(TacticalLines.ICE_EDGE_RADAR_GE);
59
+ break;
60
+ }
61
+
62
+ case TacticalLines.CRACKS_SPECIFIC_LOCATION: {
63
+ tg.set_LineType(TacticalLines.CRACKS_SPECIFIC_LOCATION_GE);
64
+ break;
65
+ }
66
+
67
+ case TacticalLines.JET: {
68
+ tg.set_LineType(TacticalLines.JET_GE);
69
+ break;
70
+ }
71
+
72
+ case TacticalLines.STREAM: {
73
+ tg.set_LineType(TacticalLines.STREAM_GE);
74
+ break;
75
+ }
76
+
77
+ case TacticalLines.FLOOD_TIDE: {
78
+ tg.set_LineType(TacticalLines.FLOOD_TIDE_GE);
79
+ break;
80
+ }
81
+
82
+ case TacticalLines.EBB_TIDE: {
83
+ tg.set_LineType(TacticalLines.EBB_TIDE_GE);
84
+ break;
85
+ }
86
+
87
+ case TacticalLines.SEAWALL: {
88
+ tg.set_LineType(TacticalLines.SEAWALL_GE);
89
+ break;
90
+ }
91
+
92
+ case TacticalLines.JETTY_BELOW_WATER: {
93
+ tg.set_LineType(TacticalLines.JETTY_BELOW_WATER_GE);
94
+ break;
95
+ }
96
+
97
+ case TacticalLines.JETTY_ABOVE_WATER: {
98
+ tg.set_LineType(TacticalLines.JETTY_ABOVE_WATER_GE);
99
+ break;
100
+ }
101
+
102
+ case TacticalLines.RAMP_BELOW_WATER: {
103
+ tg.set_LineType(TacticalLines.RAMP_BELOW_WATER_GE);
104
+ break;
105
+ }
106
+
107
+ case TacticalLines.RAMP_ABOVE_WATER: {
108
+ tg.set_LineType(TacticalLines.RAMP_ABOVE_WATER_GE);
109
+ break;
110
+ }
111
+
112
+ case TacticalLines.PIER: {
113
+ tg.set_LineType(TacticalLines.PIER_GE);
114
+ break;
115
+ }
116
+
117
+ case TacticalLines.COASTLINE: {
118
+ tg.set_LineType(TacticalLines.COASTLINE_GE);
119
+ break;
120
+ }
121
+
122
+ case TacticalLines.DEPTH_CONTOUR: {
123
+ tg.set_LineType(TacticalLines.DEPTH_CONTOUR_GE);
124
+ break;
125
+ }
126
+
127
+ case TacticalLines.DEPTH_CURVE: {
128
+ tg.set_LineType(TacticalLines.DEPTH_CURVE_GE);
129
+ break;
130
+ }
131
+
132
+ case TacticalLines.CRACKS: {
133
+ tg.set_LineType(TacticalLines.CRACKS_GE);
134
+ break;
135
+ }
136
+
137
+ case TacticalLines.ESTIMATED_ICE_EDGE: {
138
+ tg.set_LineType(TacticalLines.ESTIMATED_ICE_EDGE_GE);
139
+ break;
140
+ }
141
+
142
+ case TacticalLines.ICE_EDGE: {
143
+ tg.set_LineType(TacticalLines.ICE_EDGE_GE);
144
+ break;
145
+ }
146
+
147
+ case TacticalLines.ISOTHERM: {
148
+ tg.set_LineType(TacticalLines.ISOTHERM_GE);
149
+ break;
150
+ }
151
+
152
+ case TacticalLines.UPPER_AIR: {
153
+ tg.set_LineType(TacticalLines.UPPER_AIR_GE);
154
+ break;
155
+ }
156
+
157
+ case TacticalLines.ISOBAR: {
158
+ tg.set_LineType(TacticalLines.ISOBAR_GE);
159
+ break;
160
+ }
161
+
162
+ case TacticalLines.ISODROSOTHERM: {
163
+ tg.set_LineType(TacticalLines.ISODROSOTHERM_GE);
164
+ break;
165
+ }
166
+
167
+ case TacticalLines.ISOTACH: {
168
+ tg.set_LineType(TacticalLines.ISOTACH_GE);
169
+ break;
170
+ }
171
+
172
+ case TacticalLines.ISOPLETHS: {
173
+ tg.set_LineType(TacticalLines.ISOPLETHS_GE);
174
+ break;
175
+ }
176
+
177
+ default: {
178
+ break;
179
+ }
180
+
181
+ }
182
+ return;
183
+ }
184
+
185
+ /**
186
+ * GE has no capability for dashed lines. This function sets each polyline in the array as a new
187
+ * polyline broken into points corresponding to the dash pattern
188
+ * @param polylines
189
+ * @param shape
190
+ */
191
+ private static createDashedPolylines(polylines: Array<Array<Point2D>>, shape: ShapeInfo): void {
192
+ try {
193
+ if (shape.getLineColor() == null) {
194
+ return;
195
+ }
196
+
197
+ let stroke: BasicStroke = shape.getStroke();
198
+ let dash: number[] = stroke.getDashArray();
199
+ if (dash == null || dash.length < 2) {
200
+ return;
201
+ }
202
+
203
+ let dashedPolylines: Array<Array<Point2D>> = new Array();
204
+
205
+ for (let polyline of polylines) {
206
+ let dashIndex: int = 0; // Current index in dash array
207
+ let remainingInIndex: double = dash[dashIndex]; // Length remaining in current dash array index
208
+ for (let i: int = 0; i < polyline.length - 1; i++) {
209
+ let segStartPt: Point2D = polyline[i]; // segment start, moves as segment is processed
210
+ let segEndPt: Point2D = polyline[i + 1]; // Segment end
211
+
212
+ let segLength: double = 0; // distance remaining in segment
213
+ while ((segLength = lineutility.CalcDistanceDouble(segStartPt, segEndPt)) > 0) {
214
+ // If the line segment length is shorter than the current dash then move to the end of the segment continuing to draw or move
215
+ // Otherwise move to the end of the current dash and start the next dash there
216
+ if (segLength < remainingInIndex) {
217
+ if (dashIndex % 2 === 0) {
218
+ // Continue line
219
+ let dashedPolyline: Array<Point2D> = new Array(segStartPt, segEndPt);
220
+ dashedPolylines.push(dashedPolyline);
221
+ }
222
+ remainingInIndex -= segLength;
223
+ break; // Next segment
224
+ } else {
225
+ // Flip to line or space at dashFlipPoint
226
+ let dashFlipPoint: Point2D = lineutility.ExtendAlongLineDouble2(segStartPt, segEndPt, remainingInIndex);
227
+ if (dashIndex % 2 === 0) {
228
+ // Continue line
229
+ let dashedPolyline: Array<Point2D> = new Array(segStartPt, dashFlipPoint);
230
+ dashedPolylines.push(dashedPolyline);
231
+ }
232
+ // Next dash
233
+ dashIndex++;
234
+ if (dashIndex >= dash.length) {
235
+
236
+ dashIndex = 0;
237
+ }
238
+
239
+ remainingInIndex = dash[dashIndex];
240
+ segStartPt = dashFlipPoint;
241
+ }
242
+ }
243
+ }
244
+ }
245
+ polylines.length = 0; // polylines.clear()
246
+ polylines.push(...dashedPolylines);
247
+ } catch (exc) {
248
+ if (exc instanceof Error) {
249
+ ErrorLogger.LogException(clsUtilityGE._className, "createDashedPolylines",
250
+ new RendererException("Failed inside createDashedPolylines", exc));
251
+ } else {
252
+ throw exc;
253
+ }
254
+ }
255
+ }
256
+ private static createSimpleFillShape(tg: TGLight, shape: ShapeInfo, polylines: Array<Array<Point2D>>): ShapeInfo | null {
257
+ try {
258
+ let s: BasicStroke = shape.getStroke();
259
+ let dash: number[] = s.getDashArray();
260
+ if (clsUtilityJTR.isClosedPolygon(tg.get_LineType()) === false) {
261
+ if (clsUtilityJTR.IsChange1Area(tg.get_LineType()) === false) {
262
+ return null;
263
+ }
264
+ }
265
+
266
+ if (dash == null || dash.length < 2) {
267
+ return null;
268
+ }
269
+
270
+ if (shape.getFillColor() == null) {
271
+ return null;
272
+ }
273
+
274
+
275
+ //if we reach this point we know it is a dashed line so we need a separate fill shape
276
+ let j: int = 0;
277
+ let k: int = 0;
278
+ let shape2: ShapeInfo = new ShapeInfo(shape.getShape());
279
+ shape2.setShapeType(ShapeInfo.SHAPE_TYPE_FILL);
280
+ let polylines2: Array<Array<Point2D>> = new Array();
281
+ let polyline: Array<Point2D>;
282
+ let polyline2: Array<Point2D>;
283
+ let pt2d: Point2D;
284
+ s = new BasicStroke(0);
285
+ shape2.setStroke(s);
286
+ shape2.setFillColor(shape.getFillColor());
287
+ let n: int = polylines.length;
288
+ //for(j=0;j<polylines.length;j++)
289
+ for (j = 0; j < n; j++) {
290
+ polyline = polylines[j];
291
+ polyline2 = new Array();
292
+ let t: int = polyline.length;
293
+ //for(k=0;k<polyline.length;k++)
294
+ for (k = 0; k < t; k++) {
295
+ pt2d = new Point2D(polyline[k].getX(), polyline[k].getY());
296
+ polyline2.push(pt2d);
297
+ }
298
+ polylines2.push(polyline2);
299
+ }
300
+ //reset our original dashed shapinfo type to polyline
301
+ shape.setShapeType(ShapeInfo.SHAPE_TYPE_POLYLINE);
302
+ //this line will prevent unecessary work by multipointhandler
303
+ shape.setFillColor(null);
304
+ shape2.setPolylines(polylines2);
305
+ // shape2.setAffineTransform(new AffineTransform());
306
+ return shape2;
307
+ } catch (exc) {
308
+ if (exc instanceof Error) {
309
+ ErrorLogger.LogException(clsUtilityGE._className, "createSimpleFillShape",
310
+ new RendererException("Failed inside createSimpleFillShape", exc));
311
+ } else {
312
+ throw exc;
313
+ }
314
+ }
315
+ return null;
316
+ }
317
+ private static createSimplePatternFillShape(tg: TGLight, shape: ShapeInfo, polylines: Array<Array<Point2D>>): ShapeInfo | null {
318
+ try {
319
+ let s: BasicStroke = shape.getStroke();
320
+ let dash: number[] = s.getDashArray();
321
+ if (clsUtilityJTR.isClosedPolygon(tg.get_LineType()) === false) {
322
+ if (clsUtilityJTR.IsChange1Area(tg.get_LineType()) === false) {
323
+ return null;
324
+ }
325
+
326
+ }
327
+
328
+ if (dash == null || dash.length < 2) {
329
+ return null;
330
+ }
331
+
332
+ if (shape.getPatternFillImage() == null) {
333
+ return null;
334
+ }
335
+
336
+
337
+ //if we reach this point we know it is a dashed line so we need a separate pattern fill shape
338
+ let j: int = 0;
339
+ let k: int = 0;
340
+ let shape2: ShapeInfo = new ShapeInfo(shape.getShape());
341
+ shape2.setShapeType(ShapeInfo.SHAPE_TYPE_FILL);
342
+ let polylines2: Array<Array<Point2D>> = new Array();
343
+ let polyline: Array<Point2D>;
344
+ let polyline2: Array<Point2D>;
345
+ let pt2d: Point2D;
346
+ s = new BasicStroke(0);
347
+ shape2.setStroke(s);
348
+ shape2.setPatternFillImage(shape.getPatternFillImageInfo());
349
+ shape2.setTexturePaint(shape.getTexturePaint());
350
+ let n: int = polylines.length;
351
+ //for(j=0;j<polylines.length;j++)
352
+ for (j = 0; j < n; j++) {
353
+ polyline = polylines[j];
354
+ polyline2 = new Array();
355
+ let t: int = polyline.length;
356
+ //for(k=0;k<polyline.length;k++)
357
+ for (k = 0; k < t; k++) {
358
+ pt2d = new Point2D(polyline[k].getX(), polyline[k].getY());
359
+ polyline2.push(pt2d);
360
+ }
361
+ polylines2.push(polyline2);
362
+ }
363
+ //reset our original dashed shapinfo type to polyline
364
+ shape.setShapeType(ShapeInfo.SHAPE_TYPE_POLYLINE);
365
+ //this line will prevent unecessary work by multipointhandler
366
+ shape.setPatternFillImage(null);
367
+ shape.setTexturePaint(null);
368
+ shape2.setPolylines(polylines2);
369
+ // shape2.setAffineTransform(new AffineTransform());
370
+ return shape2;
371
+ } catch (exc) {
372
+ if (exc instanceof Error) {
373
+ ErrorLogger.LogException(clsUtilityGE._className, "createSimplePatternFillShape",
374
+ new RendererException("Failed inside createSimplePatternFillShape", exc));
375
+ } else {
376
+ throw exc;
377
+ }
378
+ }
379
+ return null;
380
+ }
381
+ private static allowFillForThese(tg: TGLight): boolean {
382
+ try {
383
+ let linetype: int = tg.get_LineType();
384
+ let bolMETOC: int = clsMETOC.IsWeather(tg.get_SymbolId());
385
+ if (bolMETOC >= 0) {
386
+
387
+ return true;
388
+ }
389
+
390
+
391
+ switch (linetype) {
392
+ case TacticalLines.BBS_AREA:
393
+ case TacticalLines.BBS_RECTANGLE:
394
+
395
+ case TacticalLines.CATK:
396
+ case TacticalLines.CATKBYFIRE:
397
+ case TacticalLines.AIRAOA:
398
+ case TacticalLines.AAAAA:
399
+ case TacticalLines.MAIN:
400
+ case TacticalLines.SPT:
401
+
402
+ case TacticalLines.SARA:
403
+ case TacticalLines.RANGE_FAN_SECTOR:
404
+ case TacticalLines.RADAR_SEARCH:
405
+ case TacticalLines.RANGE_FAN:
406
+ case TacticalLines.MNFLDFIX:
407
+ case TacticalLines.TURN:
408
+ case TacticalLines.MNFLDDIS:
409
+ //case TacticalLines.OVERHEAD_WIRE:
410
+ case TacticalLines.EASY:
411
+ case TacticalLines.ATDITCHC:
412
+ case TacticalLines.ATDITCHM:
413
+ case TacticalLines.FERRY:
414
+ case TacticalLines.BYDIF:
415
+ case TacticalLines.BYIMP:
416
+ case TacticalLines.DEPTH_AREA: {
417
+ return true;
418
+ }
419
+
420
+ default: {
421
+ return false;
422
+ }
423
+
424
+ }
425
+ } catch (exc) {
426
+ if (exc instanceof Error) {
427
+ ErrorLogger.LogException(clsUtilityGE._className, "allowFillForThese",
428
+ new RendererException("Failed inside allowFillForThese", exc));
429
+ } else {
430
+ throw exc;
431
+ }
432
+ }
433
+ return false;
434
+ }
435
+ static SetShapeInfosPolylines(tg: TGLight, shapeInfos: Array<ShapeInfo>, clipBounds: Rectangle2D | Rectangle | Array<Point2D> | null): void {
436
+ try {
437
+ let j: int = 0;
438
+ let shape: Shape;
439
+ let shapeInfo: ShapeInfo;
440
+ let polylines: Array<Array<Point2D>>;
441
+ let type: int = -1;
442
+ let simpleFillShape: ShapeInfo;//diagnostic
443
+ let isClosed: boolean = clsUtilityJTR.isClosedPolygon(tg.get_LineType());
444
+ let linetype: int = tg.get_LineType();
445
+ let fillColor: Color;
446
+ let n: int = shapeInfos.length;
447
+ //for(j=0;j<shapeInfos.length;j++)
448
+ for (j = 0; j < n; j++) {
449
+ shapeInfo = shapeInfos[j];
450
+ type = shapeInfo.getShapeType();
451
+ shape = shapeInfo.getShape();
452
+ if (isClosed === false && type !== Shape2.SHAPE_TYPE_FILL) {
453
+ polylines = clsUtilityGE.createRenderablesFromShape(tg, shape, type, clipBounds);
454
+ }
455
+
456
+ else {
457
+
458
+ polylines = clsUtilityGE.createRenderablesFromShape(tg, shape, type, null);
459
+ }
460
+
461
+ //create a simple fill shape here and change the shape type to SHAPE_TYPE_POLYLINE if it has non-null dash
462
+ //add the simple fill shape to shapeInfos after the loop
463
+ if (simpleFillShape == null) {
464
+ simpleFillShape = clsUtilityGE.createSimpleFillShape(tg, shapeInfo, polylines);
465
+ }
466
+
467
+ if (simpleFillShape == null) {
468
+ simpleFillShape = clsUtilityGE.createSimplePatternFillShape(tg, shapeInfo, polylines);
469
+ }
470
+
471
+
472
+ fillColor = shapeInfo.getFillColor();
473
+ //if(simpleFillShape!=null || fillColor != null)//the symbol has a basic fill shape
474
+ if (simpleFillShape != null) {
475
+ //the symbol has a basic fill shape
476
+ if (clsUtilityGE.allowFillForThese(tg) === false) {
477
+
478
+ shapeInfo.setFillColor(null);
479
+ }
480
+
481
+ }
482
+
483
+
484
+ if (!tg.get_UseDashArray()) {
485
+ clsUtilityGE.createDashedPolylines(polylines, shapeInfo);
486
+ }
487
+
488
+
489
+ shapeInfo.setPolylines(polylines);
490
+ }
491
+ if (simpleFillShape != null) {
492
+ shapeInfos.splice(0, 0, simpleFillShape);
493
+ }
494
+
495
+ } catch (exc) {
496
+ if (exc instanceof Error) {
497
+ ErrorLogger.LogException(clsUtilityGE._className, "SetShapeInfosPolylines",
498
+ new RendererException("Failed inside SetShapeInfosPolylines", exc));
499
+ } else {
500
+ throw exc;
501
+ }
502
+ }
503
+ }
504
+ /**
505
+ * Separates the Shape into separate polylines, eas as an ArrayList of Point2D
506
+ * @param shape
507
+ * @return
508
+ */
509
+ private static createRenderablesFromShape(tg: TGLight, shape: Shape, shapeType: int, clipArea: Rectangle2D | Rectangle | Array<Point2D> | null | null): Array<Array<Point2D>> {
510
+ let ptsPoly: Array<Point2D> = new Array();
511
+ let polylines2: Array<Array<Point2D>> = new Array<Array<Point2D>>();
512
+ let ptPoly: Point2D;
513
+ try {
514
+ //this is not going to work for splines
515
+ let coords: number[] = new Array<number>(6);
516
+ for (let i: PathIterator = shape.getPathIterator(null); !i.isDone(); i.next()) {
517
+ let type: int = i.currentSegment(coords);
518
+ switch (type) {
519
+ case PathIterator.SEG_MOVETO: {
520
+ //newshape.moveTo(coords[0], coords[1]);
521
+ //finalize the last Polyline and add it to the array
522
+ if (ptsPoly.length > 0) {
523
+ if (shapeType === ShapeInfo.SHAPE_TYPE_FILL) {
524
+ if (ptsPoly[ptsPoly.length - 1].getX() !== ptsPoly[0].getX() ||
525
+ ptsPoly[ptsPoly.length - 1].getY() !== ptsPoly[0].getY()) {
526
+ let pt2d: Point2D = new Point2D(ptsPoly[0].getX(), ptsPoly[0].getY());
527
+ ptsPoly.push(pt2d);
528
+ }
529
+ }
530
+ if (ptsPoly.length > 1) {
531
+
532
+ polylines2.push(ptsPoly);
533
+ }
534
+
535
+ }
536
+ //start the ArrayList for next Polyline
537
+ ptsPoly = new Array();
538
+ ptPoly = new Point2D(coords[0], coords[1]);
539
+ ptsPoly.push(ptPoly);
540
+ break;
541
+ }
542
+
543
+ case PathIterator.SEG_LINETO: {
544
+ //newshape.lineTo(coords[0], coords[1]);
545
+ ptPoly = new Point2D(coords[0], coords[1]);
546
+ ptsPoly.push(ptPoly);
547
+ break;
548
+ }
549
+
550
+ case PathIterator.SEG_QUADTO: { //quadTo was never used
551
+ //no idea what to do with this
552
+ //newshape.quadTo(coords[0], coords[1], coords[2], coords[3]);
553
+ break;
554
+ }
555
+
556
+ case PathIterator.SEG_CUBICTO: { //curveTo was used for some METOC's
557
+ //no idea what to do with these
558
+ //newshape.curveTo(coords[0], coords[1], coords[2], coords[3],
559
+ // coords[4], coords[5]);
560
+ break;
561
+ }
562
+
563
+ case PathIterator.SEG_CLOSE: { //closePath was never used
564
+ //newshape.closePath();
565
+ break;
566
+ }
567
+
568
+
569
+ default:
570
+
571
+ }
572
+ }
573
+ if (ptsPoly.length > 1) {
574
+ //add the last line to the ArrayList
575
+ //if it is a fill shape then the Google Earth linear ring requires the last point be added
576
+ if (shapeType === ShapeInfo.SHAPE_TYPE_FILL) {
577
+ if (ptsPoly[ptsPoly.length - 1].getX() !== ptsPoly[0].getX() ||
578
+ ptsPoly[ptsPoly.length - 1].getY() !== ptsPoly[0].getY()) {
579
+ let pt2d: Point2D = new Point2D(ptsPoly[0].getX(), ptsPoly[0].getY());
580
+ ptsPoly.push(pt2d);
581
+ }
582
+ }
583
+ polylines2.push(ptsPoly);
584
+ }
585
+ } catch (exc) {
586
+ if (exc instanceof Error) {
587
+ ErrorLogger.LogException(clsUtilityGE._className, "createRenderableFromShape",
588
+ new RendererException("Failed inside createRenderableFromShape", exc));
589
+ } else {
590
+ throw exc;
591
+ }
592
+ }
593
+ //return newshape;
594
+ return polylines2;
595
+ }
596
+ /**
597
+ * Assumes a convex polygon for the clipping area.
598
+ * expand the polygon using pixels and a similar algorithm to what flash renderer does for DEPTH AREA
599
+ * @param pts clipping area to expand
600
+ * @param expand pixels expansion
601
+ * @return
602
+ */
603
+ static expandPolygon(pts: Array<Point2D>,
604
+ expand: double): Array<Point2D> {
605
+ let lgPoly: Array<Point2D>;
606
+ try {
607
+ let j: int = 0;
608
+ let destPts: Point2D[];
609
+ let isClosed: boolean = false;
610
+ if (pts[pts.length - 1].getX() === pts[0].getX() && pts[pts.length - 1].getY() === pts[0].getY()) {
611
+ pts.splice(pts.length - 1, 1);
612
+ isClosed = true;
613
+ }
614
+ let pts2: Array<POINT2> = clsUtility.Points2DToPOINT2(pts);
615
+ let pt0: POINT2;
616
+ let pt1: POINT2;
617
+ let pt2: POINT2;
618
+ let pt3: POINT2;
619
+ let m: double = 0;
620
+ let m1: double = 0;
621
+ let b: double = 0;
622
+ let b1: double = 0;
623
+ let lineSegments: Array<Line2D> = new Array();
624
+ //n vertical segments
625
+ let n: int = pts2.length;
626
+ //for(j=0;j<pts2.length-1;j++)
627
+ for (j = 0; j < n - 1; j++) {
628
+ pt0 = new POINT2(pts2[j]);
629
+ pt1 = new POINT2(pts2[j + 1]);
630
+ //no vertical segments
631
+ if (pt0.x === pt1.x) {
632
+ pt1.x += 1;
633
+ pts2[j + 1] = pt1;
634
+ }
635
+ }
636
+ let ptn: POINT2 = pts2[pts2.length - 1];
637
+ pt0 = new POINT2(pts2[0]);
638
+ //last segment not vertical
639
+ if (ptn.x === pt0.x) {
640
+ ptn.x += 1;
641
+ pts2[pts2.length - 1] = ptn;
642
+ }
643
+ //close pts2
644
+ pts2.push(pt0);;
645
+
646
+ //POINT2 ptOther=null;
647
+ //int quadrant=-1,otherQuadrant=-1;
648
+ let poly: Polygon = new Polygon();
649
+ n = pts2.length;
650
+ //for(j=0;j<pts2.length;j++)
651
+ for (j = 0; j < n; j++) {
652
+
653
+ poly.addPoint(pts2[j].x as int, pts2[j].y as int);
654
+ }
655
+
656
+
657
+ let lineSegment: Line2D;
658
+ let midPt: POINT2;
659
+ //pts2 is closed
660
+ n = pts2.length;
661
+ //for(j=0;j<pts2.length-1;j++)
662
+ for (j = 0; j < n - 1; j++) {
663
+ pt0 = new POINT2(pts2[j]);
664
+ pt1 = new POINT2(pts2[j + 1]);
665
+ m = (pt0.y - pt1.y) / (pt0.x - pt1.x);
666
+ //m1=-1/m;
667
+ if (Math.abs(m) < 1) {
668
+ pt2 = lineutility.ExtendDirectedLine(pt0, pt1, pt0, lineutility.extend_above, expand);
669
+ pt3 = lineutility.ExtendDirectedLine(pt0, pt1, pt1, lineutility.extend_above, expand);
670
+ midPt = lineutility.MidPointDouble(pt2, pt3, 0);
671
+ //we want the polygon to not contain the extended points
672
+ if (poly.contains(midPt.x, midPt.y)) {
673
+ pt2 = lineutility.ExtendDirectedLine(pt0, pt1, pt0, lineutility.extend_below, expand);
674
+ pt3 = lineutility.ExtendDirectedLine(pt0, pt1, pt1, lineutility.extend_below, expand);
675
+ }
676
+ }
677
+ else {
678
+ pt2 = lineutility.ExtendDirectedLine(pt0, pt1, pt0, lineutility.extend_left, expand);
679
+ pt3 = lineutility.ExtendDirectedLine(pt0, pt1, pt1, lineutility.extend_left, expand);
680
+ midPt = lineutility.MidPointDouble(pt2, pt3, 0);
681
+ //we want the polygon to not contain the extended points
682
+ if (poly.contains(midPt.x, midPt.y)) {
683
+ pt2 = lineutility.ExtendDirectedLine(pt0, pt1, pt0, lineutility.extend_right, expand);
684
+ pt3 = lineutility.ExtendDirectedLine(pt0, pt1, pt1, lineutility.extend_right, expand);
685
+ }
686
+ }
687
+ lineSegment = new Line2D(pt2.x, pt2.y, pt3.x, pt3.y);
688
+ lineSegments.push(lineSegment);
689
+ }
690
+ //we will intersect the line segments to form an expanded polygon
691
+ let expandPts: Array<POINT2> = new Array();
692
+ let thisLine: Line2D;
693
+ let nextLine: Line2D;
694
+ let x1: double = 0;
695
+ let y1: double = 0;
696
+ let x2: double = 0;
697
+ let y2: double = 0;
698
+ let x: double = 0;
699
+ let y: double = 0;
700
+ let t: int = lineSegments.length;
701
+ //for(j=0;j<lineSegments.length;j++)
702
+ for (j = 0; j < t; j++) {
703
+ thisLine = lineSegments[j];
704
+ x1 = thisLine.getX1();
705
+ y1 = thisLine.getY1();
706
+ x2 = thisLine.getX2();
707
+ y2 = thisLine.getY2();
708
+ //thisLine line equation
709
+ m = (y1 - y2) / (x1 - x2);
710
+ b = y1 - m * x1;
711
+
712
+ if (j === lineSegments.length - 1) {
713
+
714
+ nextLine = lineSegments[0];
715
+ }
716
+
717
+ else {
718
+
719
+ nextLine = lineSegments[j + 1];
720
+ }
721
+
722
+
723
+ x1 = nextLine.getX1();
724
+ y1 = nextLine.getY1();
725
+ x2 = nextLine.getX2();
726
+ y2 = nextLine.getY2();
727
+ //nextLine line equation
728
+ m1 = (y1 - y2) / (x1 - x2);
729
+ b1 = y1 - m1 * x1;
730
+
731
+ //intersect thisLine with nextLine
732
+ if (m !== m1) {
733
+ x = (b1 - b) / (m - m1); //cannot blow up
734
+ y = (m * x + b);
735
+ }
736
+ else //this should not happen
737
+ {
738
+ x = thisLine.getX2();
739
+ y = thisLine.getY2();
740
+ }
741
+ expandPts.push(new POINT2(x, y));
742
+ }
743
+ lgPoly = new Array();
744
+ t = expandPts.length;
745
+ //for(j=0;j<expandPts.length;j++)
746
+ for (j = 0; j < t; j++) {
747
+
748
+ lgPoly.push(new Point2D(expandPts[j].x, expandPts[j].y));
749
+ }
750
+
751
+
752
+ //close the aray if the original clipping array if applicable
753
+ if (isClosed) {
754
+
755
+ lgPoly.push(new Point2D(lgPoly[0].getX(), lgPoly[0].getY()));
756
+ }
757
+
758
+ } catch (exc) {
759
+ if (exc instanceof Error) {
760
+ ErrorLogger.LogException(clsUtilityGE._className, "expandPolygon2",
761
+ new RendererException("Failed inside expandPolygon2", exc));
762
+ } else {
763
+ throw exc;
764
+ }
765
+ }
766
+ return lgPoly;
767
+ }
768
+ /**
769
+ * use cheap algorithm to expand polygons, works best on regular 4+ sided convex polygons
770
+ * used primarily for expanding the original clipping areas. After clipping a tactical line against
771
+ * the expanded clipping area, the original clipping area can be used to drop the clip lines
772
+ * @param pts points to expand, usually a clipping area
773
+ * @param expandX X expansion factor, e.g 10% growth would be 1.1
774
+ * @param expandY Y expansion factor
775
+ * @return points for the expanded polygon
776
+ */
777
+ protected static expandPolygon2(pts: Array<Point2D>,
778
+ expandX: double,
779
+ expandY: double): Array<Point2D> {
780
+ let lgPoly: Array<Point2D>;
781
+ try {
782
+ // AffineTransform at=new AffineTransform();
783
+ // at.setToIdentity();
784
+ //get the center of the pts using an average
785
+ let avgX: double = 0;
786
+ let avgY: double = 0;
787
+ let totalX: double = 0;
788
+ let totalY: double = 0;
789
+ let j: int = 0;
790
+ let isClosed: boolean = false;
791
+ //open the array, remove the last point if necessary
792
+ if (pts[pts.length - 1].getX() === pts[0].getX() && pts[pts.length - 1].getY() === pts[0].getY()) {
793
+ pts.splice(pts.length - 1, 1);
794
+ isClosed = true;
795
+ }
796
+ //asumes open array
797
+ let n: int = pts.length;
798
+ //for(j=0;j<pts.length;j++)
799
+ for (j = 0; j < n; j++) {
800
+ totalX += pts[j].getX();
801
+ totalY += pts[j].getY();
802
+ }
803
+ avgX = totalX / pts.length;
804
+ avgY = totalY / pts.length;
805
+ let srcPts: Point2D[] = new Array<Point2D>(pts.length);
806
+ //for(j=0;j<pts.length;j++)
807
+ n = pts.length;
808
+ for (j = 0; j < n; j++) {
809
+ srcPts[j] = new Point2D(pts[j].getX(), pts[j].getY());
810
+ }
811
+ let destPts: Point2D[] = new Array<Point2D>(pts.length);
812
+ //translate the points to crcumscribe 0,0
813
+ // at.translate(-avgY, -avgY);//ideally would be close to 0
814
+ // at.transform(srcPts, 0, destPts, 0, srcPts.length);
815
+ // at.setToIdentity();
816
+ //scale the points by 10%
817
+ // at.scale(expandX, expandY);
818
+ // at.transform(destPts, 0, destPts, 0, destPts.length);
819
+ // at.setToIdentity();
820
+ // at.translate(avgY, avgY);
821
+ // at.transform(destPts, 0, destPts, 0, destPts.length);
822
+ lgPoly = new Array<Point2D>();
823
+ let t: int = destPts.length;
824
+ //for(j=0;j<destPts.length;j++)
825
+ for (j = 0; j < t; j++) {
826
+ lgPoly.push(destPts[j]);
827
+ }
828
+ //close the aray if the original clipping array was closed
829
+ if (isClosed) {
830
+
831
+ lgPoly.push(new Point2D(destPts[0].getX(), destPts[0].getY()));
832
+ }
833
+
834
+ } catch (exc) {
835
+ if (exc instanceof Error) {
836
+ ErrorLogger.LogException(clsUtilityGE._className, "expandPolygon",
837
+ new RendererException("Failed inside expandPolygon", exc));
838
+ } else {
839
+ throw exc;
840
+ }
841
+ }
842
+ return lgPoly;
843
+ }
844
+ /**
845
+ * @deprecated
846
+ * For tactical lines break up the arraylists into separate arraylists within the bounds.
847
+ * This was added for the Google Earth 3D map because small scales cut off and we want the clip lines
848
+ * to not be visible.
849
+ * @param ptsPoly
850
+ * @param clipBounds
851
+ * @return
852
+ */
853
+ private static ptsPolyToPtsPoly(tg: TGLight, ptsPoly: Array<Array<Point2D>>,
854
+ clipBounds: Rectangle2D): Array<Array<Point2D>>;
855
+ /**
856
+ * @deprecated
857
+ * function to remove the clip lines from the polygon that was clipped
858
+ * @param ptsPoly the clipped points array
859
+ * @param clipBounds the clipping points
860
+ * @return
861
+ */
862
+ private static ptsPolyToPtsPoly(tg: TGLight, ptsPoly: Array<Array<Point2D>>,
863
+ clipBounds: Array<Point2D>): Array<Array<Point2D>>;
864
+ private static ptsPolyToPtsPoly(...args: unknown[]): Array<Array<Point2D>> {
865
+ if (args[2] instanceof Rectangle2D) {
866
+ const [tg, ptsPoly, clipBounds] = args as [TGLight, Array<Array<Point2D>>, Rectangle2D];
867
+
868
+
869
+ let ptsPoly2: Array<Array<Point2D>>;
870
+ try {
871
+ if (clsUtilityJTR.IsChange1Area(tg.get_LineType()) === true) {
872
+ return ptsPoly;
873
+ }
874
+
875
+
876
+ let j: int = 0;
877
+ let k: int = 0;
878
+ let pts: Array<Point2D>;
879
+ let addPts: Array<Point2D>;
880
+ let pt0: Point2D;
881
+ let pt1: Point2D;
882
+ let line: Line2D;
883
+ ptsPoly2 = new Array();
884
+ let n: int = ptsPoly.length;
885
+ //for(j=0;j<ptsPoly.length;j++)
886
+ for (j = 0; j < n; j++) {
887
+ addPts = null;
888
+ pts = ptsPoly[j];
889
+ //find the first point inside the clipbounds
890
+ let t: int = pts.length;
891
+ //for(k=0;k<pts.length-1;k++)
892
+ for (k = 0; k < t - 1; k++) {
893
+ pt0 = pts[k];
894
+ pt1 = pts[k + 1];
895
+
896
+ line = new Line2D(pt0, pt1);
897
+ //both points out of bounds, do not add points
898
+ if (clipBounds.contains(pt0) === false && clipBounds.contains(pt1) === false) {
899
+ if (clipBounds.intersectsLine(line) === false) {
900
+ addPts = null;
901
+ continue;
902
+ }
903
+ else {
904
+ if (addPts == null) {
905
+ addPts = new Array();
906
+ addPts.push(pt0);
907
+ }
908
+ if (addPts.includes(pt0) === false) {
909
+
910
+ addPts.push(pt0);
911
+ }
912
+
913
+
914
+ addPts.push(pt1);
915
+ ptsPoly2.push(addPts);
916
+ addPts = null;
917
+ }
918
+ }
919
+ else {
920
+ if (clipBounds.contains(pt0) === false && clipBounds.contains(pt1) === true) {
921
+ if (addPts == null) {
922
+ addPts = new Array();
923
+ addPts.push(pt0);
924
+ }
925
+ if (addPts.includes(pt0) === false) {
926
+
927
+ addPts.push(pt0);
928
+ }
929
+
930
+
931
+ addPts.push(pt1);
932
+ }
933
+ else {
934
+ if (clipBounds.contains(pt0) === true && clipBounds.contains(pt1) === true) {
935
+ if (addPts == null) {
936
+ addPts = new Array();
937
+ addPts.push(pt0);
938
+ }
939
+ if (addPts.includes(pt0) === false) {
940
+
941
+ addPts.push(pt0);
942
+ }
943
+
944
+
945
+ addPts.push(pt1);
946
+ }
947
+ else {
948
+ if (clipBounds.contains(pt0) === true && clipBounds.contains(pt1) === false) {
949
+ if (addPts == null) {
950
+ addPts = new Array();
951
+ addPts.push(pt0);
952
+ }
953
+ if (addPts.includes(pt0) === false) {
954
+
955
+ addPts.push(pt0);
956
+ }
957
+
958
+ //end the current polyline
959
+ //and add it to the array list
960
+ addPts.push(pt1);
961
+ ptsPoly2.push(addPts);
962
+ addPts = null;
963
+ }
964
+ }
965
+
966
+ }
967
+
968
+ }
969
+
970
+ }
971
+ //add the final array list
972
+ if (addPts != null && addPts.length > 0) {
973
+
974
+ ptsPoly2.push(addPts);
975
+ }
976
+
977
+ }
978
+ } catch (exc) {
979
+ if (exc instanceof Error) {
980
+ ErrorLogger.LogException(clsUtilityGE._className, "ptsPolyToPtsPoly",
981
+ new RendererException("Failed inside ptsPolyToPtsPoly", exc));
982
+ } else {
983
+ throw exc;
984
+ }
985
+ }
986
+ return ptsPoly2;
987
+ } else {
988
+ const [tg, ptsPoly, clipBounds] = args as [TGLight, Array<Array<Point2D>>, Array<Point2D>];
989
+
990
+ let ptsPoly2: Array<Array<Point2D>>;
991
+ try {
992
+ if (clsUtilityJTR.IsChange1Area(tg.get_LineType()) === true) {
993
+ return ptsPoly;
994
+ }
995
+
996
+
997
+ let j: int = 0;
998
+ let k: int = 0;
999
+ let pts: Array<Point2D>;
1000
+ let addPts: Array<Point2D>;
1001
+ let pt0: Point2D;
1002
+ let pt1: Point2D;
1003
+ let line: Line2D;
1004
+ ptsPoly2 = new Array();
1005
+ let clipPoly: Polygon = new Polygon();
1006
+
1007
+ //ArrayList<Point2D>ptsClipArea=null;
1008
+ let n: int = clipBounds.length;
1009
+ //for(j=0;j<clipBounds.length;j++)
1010
+ for (j = 0; j < n; j++) {
1011
+ clipPoly.addPoint(clipBounds[j].getX() as int, clipBounds[j].getY() as int);
1012
+ }
1013
+ n = ptsPoly.length;
1014
+ //for(j=0;j<ptsPoly.length;j++)
1015
+ for (j = 0; j < n; j++) {
1016
+ addPts = null;
1017
+ pts = ptsPoly[j];
1018
+ //find the first point inside the clipbounds
1019
+ let t: int = pts.length;
1020
+ //for(k=0;k<pts.length-1;k++)
1021
+ for (k = 0; k < t - 1; k++) {
1022
+ pt0 = pts[k];
1023
+ pt1 = pts[k + 1];
1024
+ line = new Line2D(pt0, pt1);
1025
+ //both points out of bounds, do not add points
1026
+ if (clipPoly.contains(pt0) === false && clipPoly.contains(pt1) === false) {
1027
+ if (clsUtilityGE.lineIntersectsClipArea(line, clipBounds) === false) {
1028
+ addPts = null;
1029
+ continue;
1030
+ }
1031
+ else {
1032
+ if (addPts == null) {
1033
+ addPts = new Array();
1034
+ addPts.push(pt0);
1035
+ }
1036
+ if (addPts.includes(pt0) === false) {
1037
+
1038
+ addPts.push(pt0);
1039
+ }
1040
+
1041
+
1042
+ addPts.push(pt1);
1043
+ ptsPoly2.push(addPts);
1044
+ addPts = null;
1045
+ }
1046
+ } else if (clipPoly.contains(pt0) === false && clipPoly.contains(pt1) === true) {
1047
+ if (addPts == null) {
1048
+ addPts = new Array();
1049
+ addPts.push(pt0);
1050
+ }
1051
+ if (addPts.includes(pt0) === false) {
1052
+
1053
+ addPts.push(pt0);
1054
+ }
1055
+
1056
+
1057
+ addPts.push(pt1);
1058
+ } else if (clipPoly.contains(pt0) === true && clipPoly.contains(pt1) === true) {
1059
+ if (addPts == null) {
1060
+ addPts = new Array();
1061
+ addPts.push(pt0);
1062
+ }
1063
+ if (addPts.includes(pt0) === false) {
1064
+
1065
+ addPts.push(pt0);
1066
+ }
1067
+
1068
+
1069
+ addPts.push(pt1);
1070
+ } else if (clipPoly.contains(pt0) === true && clipPoly.contains(pt1) === false) {
1071
+ if (addPts == null) {
1072
+ addPts = new Array();
1073
+ addPts.push(pt0);
1074
+ }
1075
+ if (addPts.includes(pt0) === false) {
1076
+
1077
+ addPts.push(pt0);
1078
+ }
1079
+
1080
+ //end the current polyline
1081
+ //and add it to the array list
1082
+ addPts.push(pt1);
1083
+ ptsPoly2.push(addPts);
1084
+ addPts = null;
1085
+ }
1086
+ }
1087
+ //add the final array list
1088
+ if (addPts != null && addPts.length > 0) {
1089
+
1090
+ ptsPoly2.push(addPts);
1091
+ }
1092
+
1093
+ }
1094
+ } catch (exc) {
1095
+ if (exc instanceof Error) {
1096
+ ErrorLogger.LogException(clsUtilityGE._className, "ptsPolyToPtsPoly",
1097
+ new RendererException("Failed inside ptsPolyToPtsPoly", exc));
1098
+ } else {
1099
+ throw exc;
1100
+ }
1101
+ }
1102
+ return ptsPoly2;
1103
+ }
1104
+ }
1105
+
1106
+ /**
1107
+ * removes leading or trailing segments after the points were clipped
1108
+ * @param tg
1109
+ * @param clipArea
1110
+ */
1111
+ static removeTrailingPoints(tg: TGLight, clipArea: Point2D[] | Rectangle | Rectangle2D): void {
1112
+ try {
1113
+ let isClosed: boolean = clsUtilityJTR.isClosedPolygon(tg.get_LineType());
1114
+ if (isClosed) {
1115
+
1116
+ return;
1117
+ }
1118
+
1119
+
1120
+ let poly: Polygon = new Polygon();
1121
+ let area: Area;
1122
+ let clipBounds: Rectangle2D;
1123
+ let clipPoints: Array<Point2D>;
1124
+ let pt2d: Point2D;
1125
+ let j: int = 0;
1126
+ if (clipArea == null) {
1127
+
1128
+ return;
1129
+ }
1130
+
1131
+ if (clipArea instanceof Rectangle2D) {
1132
+ clipBounds = clipArea as Rectangle2D;
1133
+ } else if (clipArea instanceof Rectangle) {
1134
+ //clipBounds=(Rectangle2D)clipArea;
1135
+ let rectx: Rectangle = clipArea as Rectangle;
1136
+ clipBounds = new Rectangle2D(rectx.x, rectx.y, rectx.width, rectx.height);
1137
+ } else if (clipArea instanceof Array) {
1138
+ clipPoints = clipArea as Array<Point2D>;
1139
+
1140
+ }
1141
+
1142
+ if (clipBounds != null) {
1143
+ clipPoints = new Array<Point2D>();
1144
+ clipPoints.push(new Point2D(clipBounds.getX(), clipBounds.getY()));
1145
+ clipPoints.push(new Point2D(clipBounds.getX() + clipBounds.getWidth(), clipBounds.getY()));
1146
+ clipPoints.push(new Point2D(clipBounds.getX() + clipBounds.getWidth(), clipBounds.getY() + clipBounds.getHeight()));
1147
+ clipPoints.push(new Point2D(clipBounds.getX(), clipBounds.getY() + clipBounds.getHeight()));
1148
+ clipPoints.push(new Point2D(clipBounds.getX(), clipBounds.getY()));
1149
+ }
1150
+
1151
+ let ptLast: Point2D = clipPoints[clipPoints.length - 1];
1152
+ let pt02d: Point2D = clipPoints[0];
1153
+ let pt12d: Point2D;
1154
+ //close the area
1155
+ if (pt02d.getX() !== ptLast.getX() || pt02d.getY() !== ptLast.getY()) {
1156
+ clipPoints.push(new Point2D(pt02d.getX(), pt02d.getY()));
1157
+ //poly.addPoint((int)pt02d.getX(),(int)pt02d.getY());
1158
+ }
1159
+ //fill the polygon
1160
+ let n: int = clipPoints.length;
1161
+ //for(j=0;j<clipPoints.length;j++)
1162
+ for (j = 0; j < n; j++) {
1163
+ pt02d = clipPoints[j];
1164
+ poly.addPoint(pt02d.getX() as int, pt02d.getY() as int);
1165
+ }
1166
+ area = new Area(poly);
1167
+ let line: Line2D;
1168
+ let pt0: POINT2;
1169
+ let pt1: POINT2;
1170
+ let intersects: boolean = false;
1171
+ let frontIndex: int = 0;
1172
+ let backIndex: int = tg.Pixels.length - 1;
1173
+ //breaks at the first leading segment that intersects the clip area
1174
+ n = tg.Pixels.length;
1175
+ //for(j=0;j<tg.Pixels.length-1;j++)
1176
+ for (j = 0; j < n - 1; j++) {
1177
+ pt0 = tg.Pixels[j];
1178
+ pt1 = tg.Pixels[j + 1];
1179
+ line = new Line2D(pt0.x, pt0.y, pt1.x, pt1.y);
1180
+ intersects = clsUtilityGE.lineIntersectsClipArea(line, clipPoints);
1181
+ if (intersects === true) {
1182
+ frontIndex = j;
1183
+ break;
1184
+ }
1185
+ else {
1186
+ if (area.contains(pt0.x as int, pt0.y as int) || area.contains(pt1.x as int, pt1.y as int)) {
1187
+ frontIndex = j;
1188
+ break;
1189
+ }
1190
+ }
1191
+
1192
+ }
1193
+ //breaks at the first trailing segment that intersects the clip area
1194
+ n = tg.Pixels.length;
1195
+ //for(j=tg.Pixels.length-1;j>0;j--)
1196
+ for (j = n - 1; j > 0; j--) {
1197
+ pt0 = tg.Pixels[j];
1198
+ pt1 = tg.Pixels[j - 1];
1199
+ line = new Line2D(pt0.x, pt0.y, pt1.x, pt1.y);
1200
+ intersects = clsUtilityGE.lineIntersectsClipArea(line, clipPoints);
1201
+ if (intersects === true) {
1202
+ backIndex = j;
1203
+ break;
1204
+ }
1205
+ else {
1206
+ if (area.contains(pt0.x as int, pt0.y as int) || area.contains(pt1.x as int, pt1.y as int)) {
1207
+ backIndex = j;
1208
+ break;
1209
+ }
1210
+ }
1211
+
1212
+ }
1213
+ let pts: Array<POINT2> = new Array();
1214
+ for (j = frontIndex; j <= backIndex; j++) {
1215
+ pt0 = new POINT2(tg.Pixels[j]);
1216
+ pts.push(pt0);
1217
+ }
1218
+ tg.Pixels = pts;
1219
+ } catch (exc) {
1220
+ if (exc instanceof Error) {
1221
+ ErrorLogger.LogException("clsRenderer", "removeTrailingPoints",
1222
+ new RendererException("Failed inside removeTrailingPoints", exc));
1223
+ } else {
1224
+ throw exc;
1225
+ }
1226
+ }
1227
+ }
1228
+ /**
1229
+ * tests of a Line2D intersects a polygon by using line.intersectsLine on each segment of the polygon
1230
+ * assumes clip clipping area was parsed to shift points of vertical segments to make them not vertical
1231
+ * @param line a clipping line in the clipping polygon
1232
+ * @param clipPts array of clip points assumed to be closed
1233
+ * @return true if the line intersects the clip bounds
1234
+ */
1235
+ private static lineIntersectsClipArea(line: Line2D,
1236
+ clipPts: Array<Point2D>): boolean {
1237
+ let result: boolean = false;
1238
+ try {
1239
+ let j: int = 0;
1240
+
1241
+ //test if polygon contains an end point
1242
+ let poly: Polygon = new Polygon();
1243
+ let n: int = clipPts.length;
1244
+ //for(j=0;j<clipPts.length;j++)
1245
+ for (j = 0; j < n; j++) {
1246
+
1247
+ poly.addPoint(clipPts[j].getX() as int, clipPts[j].getY() as int);
1248
+ }
1249
+
1250
+
1251
+ if (poly.contains(line.getX1(), line.getY1())) {
1252
+
1253
+ return true;
1254
+ }
1255
+
1256
+ if (poly.contains(line.getX2(), line.getY2())) {
1257
+
1258
+ return true;
1259
+ }
1260
+
1261
+ //end section
1262
+
1263
+ let currentSegment: Line2D;
1264
+ n = clipPts.length;
1265
+ //for(j=0;j<clipPts.length-1;j++)
1266
+ for (j = 0; j < n - 1; j++) {
1267
+ currentSegment = new Line2D(clipPts[j].getX(), clipPts[j].getY(), clipPts[j + 1].getX(), clipPts[j + 1].getY());
1268
+ if (line.intersectsLine(currentSegment) === true) {
1269
+
1270
+ return true;
1271
+ }
1272
+
1273
+ }
1274
+ //if the clipPts are not closed then the above loop did not test the closing segment
1275
+ let pt0: Point2D = clipPts[0];
1276
+ let ptLast: Point2D = clipPts[clipPts.length - 1];
1277
+ //int n=clipPts.length-1;
1278
+ if (pt0.getX() !== ptLast.getX() || pt0.getY() !== ptLast.getY()) {
1279
+ //currentSegment=new Line2D(clipPts[n].getX(),clipPts[n].getY(),clipPts[0].getX(),clipPts[0].getY());
1280
+ currentSegment = new Line2D(ptLast.getX(), ptLast.getY(), pt0.getX(), pt0.getY());
1281
+ if (line.intersectsLine(currentSegment) === true) {
1282
+
1283
+ return true;
1284
+ }
1285
+
1286
+ }
1287
+ } catch (exc) {
1288
+ if (exc instanceof Error) {
1289
+ ErrorLogger.LogException(clsUtilityGE._className, "lineIntersectsClipArea",
1290
+ new RendererException("Failed inside lineIntersectsClipArea", exc));
1291
+ } else {
1292
+ throw exc;
1293
+ }
1294
+ }
1295
+ return result;
1296
+ }
1297
+ /**
1298
+ * returns true if segment data set for MSR, ASR, Boundary
1299
+ * @param tg
1300
+ * @return
1301
+ */
1302
+ protected static segmentColorsSet(tg: TGLight): boolean {
1303
+ try {
1304
+ switch (tg.get_LineType()) {
1305
+ case TacticalLines.BOUNDARY:
1306
+ case TacticalLines.MSR:
1307
+ case TacticalLines.ASR:
1308
+ case TacticalLines.ROUTE: {
1309
+ break;
1310
+ }
1311
+
1312
+ default: {
1313
+ return false;
1314
+ }
1315
+
1316
+ }
1317
+ let strH: string = tg.get_H();
1318
+ if (strH == null || strH.length === 0) {
1319
+
1320
+ return false;
1321
+ }
1322
+
1323
+ let strs: string[] = strH.split(",");
1324
+ if (strs.length > 1) {
1325
+
1326
+ return true;
1327
+ }
1328
+
1329
+ } catch (exc) {
1330
+ if (exc instanceof Error) {
1331
+ ErrorLogger.LogException(clsUtilityGE._className, "segmentColorsSet",
1332
+ new RendererException("Failed inside segmentColorsSet", exc));
1333
+ } else {
1334
+ throw exc;
1335
+ }
1336
+ }
1337
+ return false;
1338
+ }
1339
+ /**
1340
+ * Use clipping rectangle or clip points to build a zoom factor if the client zoomed in after the initial render.
1341
+ * Multiply the geo segmenting interval by this factor.
1342
+ * @param rect
1343
+ * @param clipPoints
1344
+ * @param pixels
1345
+ * @return
1346
+ */
1347
+ static getZoomFactor(rect: Rectangle2D, clipPoints: Array<Point2D>, pixels: Array<POINT2>): double {
1348
+ let factor: double = -1;
1349
+ try {
1350
+ if (pixels == null || pixels.length < 2) {
1351
+
1352
+ return factor;
1353
+ }
1354
+
1355
+ if (clipPoints == null && rect == null) {
1356
+
1357
+ return factor;
1358
+ }
1359
+
1360
+ let maxLengthPixels: double = 0;
1361
+ let maxLengthClipArea: double = 0;
1362
+ let temp: double = 0;
1363
+ let j: int = 0;
1364
+ let pt2d0: Point2D;
1365
+ let pt2d1: Point2D; let pt0: POINT2;
1366
+ let pt1: POINT2;
1367
+ for (j = 0; j < pixels.length - 1; j++) {
1368
+ pt0 = pixels[j];
1369
+ pt1 = pixels[j + 1];
1370
+ temp = lineutility.CalcDistanceDouble(pt0, pt1);
1371
+ if (temp > maxLengthPixels) {
1372
+
1373
+ maxLengthPixels = temp;
1374
+ }
1375
+
1376
+ }
1377
+ temp = 0;
1378
+ if (clipPoints != null) {
1379
+ for (j = 0; j < clipPoints.length - 1; j++) {
1380
+ pt2d0 = clipPoints[j];
1381
+ pt2d1 = clipPoints[j + 1];
1382
+ pt0 = new POINT2(pt2d0.getX(), pt2d0.getY());
1383
+ pt1 = new POINT2(pt2d1.getX(), pt2d1.getY());
1384
+ temp = lineutility.CalcDistanceDouble(pt0, pt1);
1385
+ }
1386
+ }
1387
+ else {
1388
+ if (rect != null) {
1389
+ temp = rect.getMaxX() - rect.getMinX();
1390
+ if (temp < rect.getMaxY() - rect.getMinY()) {
1391
+
1392
+ temp = rect.getMaxY() - rect.getMinY();
1393
+ }
1394
+
1395
+ }
1396
+ }
1397
+
1398
+ if (temp > maxLengthClipArea) {
1399
+
1400
+ maxLengthClipArea = temp;
1401
+ }
1402
+
1403
+ if (maxLengthPixels > 0 && maxLengthClipArea > 0) {
1404
+
1405
+ factor = maxLengthClipArea / maxLengthPixels;
1406
+ }
1407
+
1408
+ } catch (exc) {
1409
+ if (exc instanceof Error) {
1410
+ ErrorLogger.LogException(clsUtilityGE._className, "getZoomFactor",
1411
+ new RendererException("Failed inside getZoomFactor", exc));
1412
+ } else {
1413
+ throw exc;
1414
+ }
1415
+ }
1416
+ return factor;
1417
+ }
1418
+
1419
+ }