@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.
- package/LICENSE +201 -0
- package/README.md +57 -0
- package/buildNode.bat +2 -0
- package/buildWeb.bat +2 -0
- package/dist/C5Ren.d.ts +6970 -0
- package/dist/C5Ren.js +2 -0
- package/dist/C5Ren.js.map +1 -0
- package/dist/LICENSE +201 -0
- package/dist/README.md +57 -0
- package/dist/armyc2.c5isr.renderer-mil-sym-ts-web-2.2.0.tgz +0 -0
- package/dist/manifest.json +4 -0
- package/dist/package.json +16 -0
- package/index.ts +169 -0
- package/package.bak +50 -0
- package/package.json +40 -0
- package/package.node.json +43 -0
- package/package.pack.json +19 -0
- package/package.packWeb.json +16 -0
- package/package.web.json +40 -0
- package/src/main/ts/android/graphics/Bitmap.ts +7 -0
- package/src/main/ts/android/graphics/Paint.ts +26 -0
- package/src/main/ts/android/graphics/Path.ts +78 -0
- package/src/main/ts/android/graphics/PointF.ts +14 -0
- package/src/main/ts/android/graphics/Rect.ts +18 -0
- package/src/main/ts/android/graphics/RectF.ts +50 -0
- package/src/main/ts/android/graphics/Region.ts +36 -0
- package/src/main/ts/android/graphics/Typeface.ts +11 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/BasicShapes.ts +99 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/CChannelPoints2.ts +34 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/CELineArray.ts +193 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/Channels.ts +2971 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/DISMSupport.ts +4008 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/POINT2.ts +93 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/Shape2.ts +89 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/TacticalLines.ts +515 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/arraysupport.ts +5403 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/countsupport.ts +1084 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/flot.ts +2173 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/lineutility.ts +4934 -0
- package/src/main/ts/armyc2/c5isr/JavaLineArray/ref.ts +7 -0
- package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/Modifier2.ts +5601 -0
- package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/P1.ts +14 -0
- package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/TGLight.ts +648 -0
- package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/clsChannelUtility.ts +647 -0
- package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/clsMETOC.ts +2994 -0
- package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/clsUtility.ts +2663 -0
- package/src/main/ts/armyc2/c5isr/JavaTacticalRenderer/mdlGeodesic.ts +669 -0
- package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsClipPolygon2.ts +971 -0
- package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsClipQuad.ts +871 -0
- package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsRenderer.ts +3507 -0
- package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsRenderer2.ts +500 -0
- package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsUtility.ts +1089 -0
- package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsUtilityCPOF.ts +2656 -0
- package/src/main/ts/armyc2/c5isr/RenderMultipoints/clsUtilityGE.ts +1419 -0
- package/src/main/ts/armyc2/c5isr/data/genc.json +1407 -0
- package/src/main/ts/armyc2/c5isr/data/msd.json +17311 -0
- package/src/main/ts/armyc2/c5isr/data/mse.json +18500 -0
- package/src/main/ts/armyc2/c5isr/data/svgd.json +31214 -0
- package/src/main/ts/armyc2/c5isr/data/svge.json +30558 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/AffineTransform.ts +10 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Area.ts +437 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/BasicStroke.ts +429 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/BasicTypes.ts +7 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/BufferedImage.ts +35 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Font.ts +111 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/FontMetrics.ts +29 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/FontRenderContext.ts +18 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/GeneralPath.ts +211 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Graphics2D.ts +80 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/IPathIterator.ts +33 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/ImageIO.ts +16 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Line2D.ts +726 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/PathIterator.ts +141 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Point.ts +112 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Point2D.ts +261 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Polygon.ts +391 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Rectangle.ts +567 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Rectangle2D.ts +445 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Shape.ts +31 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/Stroke.ts +18 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/TextLayout.ts +45 -0
- package/src/main/ts/armyc2/c5isr/graphics2d/TexturePaint.ts +25 -0
- package/src/main/ts/armyc2/c5isr/renderer/IIconRenderer.ts +15 -0
- package/src/main/ts/armyc2/c5isr/renderer/IconRenderer.ts +22 -0
- package/src/main/ts/armyc2/c5isr/renderer/MilStdIconRenderer.ts +269 -0
- package/src/main/ts/armyc2/c5isr/renderer/ModifierRenderer.ts +9882 -0
- package/src/main/ts/armyc2/c5isr/renderer/PatternFillRenderer.ts +146 -0
- package/src/main/ts/armyc2/c5isr/renderer/SinglePointSVGRenderer.ts +1265 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/arc.ts +64 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/bcurve.ts +95 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/ellipse.ts +93 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/line.ts +114 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/path.ts +555 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/pathiterator.ts +62 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/point.ts +120 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/rectangle.ts +431 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/roundedrectangle.ts +99 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/types.ts +25 -0
- package/src/main/ts/armyc2/c5isr/renderer/shapes/utilities.ts +203 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/AffiliationColors.ts +104 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/Color.ts +481 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/DistanceUnit.ts +40 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/DrawRules.ts +1323 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/EntityCode.ts +51 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/ErrorLogger.ts +736 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/GENCLookup.ts +106 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/GeoPixelConversion3D.ts +84 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/IMultiPointRenderer.ts +87 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/IPointConversion.ts +34 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/ImageInfo.ts +324 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/LRUCache.ts +127 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/LRUEntry.ts +18 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/LogLevel.ts +111 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/MODrawRules.ts +219 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/MSInfo.ts +1008 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/MSLookup.ts +882 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/MilStdAttributes.ts +380 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/MilStdSymbol.ts +797 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/Modifiers.ts +1699 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/PointConversion.ts +178 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/PointConversionDummy.ts +45 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/PointConverter3D.ts +126 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/RectUtilities.ts +118 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/RendererException.ts +11 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/RendererSettings.ts +1201 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/RendererUtilities.ts +591 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/SVGInfo.ts +29 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/SVGLookup.ts +753 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/SVGSymbolInfo.ts +137 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/SVGTextInfo.ts +438 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/SettingsChangedEvent.ts +19 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/SettingsChangedEventListener.ts +10 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/SettingsEventListener.ts +5 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/Shape2SVG.ts +404 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/ShapeInfo.ts +525 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/ShapeUtilities.ts +55 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/SymbolDimensionInfo.ts +36 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/SymbolID.ts +1055 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/SymbolUtilities.ts +2085 -0
- package/src/main/ts/armyc2/c5isr/renderer/utilities/TextInfo.ts +157 -0
- package/src/main/ts/armyc2/c5isr/web/render/GeoPixelConversion.ts +86 -0
- package/src/main/ts/armyc2/c5isr/web/render/MultiPointHandler.ts +3798 -0
- package/src/main/ts/armyc2/c5isr/web/render/MultiPointHandlerSVG.ts +412 -0
- package/src/main/ts/armyc2/c5isr/web/render/PointConverter.ts +124 -0
- package/src/main/ts/armyc2/c5isr/web/render/SymbolModifiers.ts +26 -0
- package/src/main/ts/armyc2/c5isr/web/render/WebRenderer.ts +677 -0
- package/src/main/ts/armyc2/c5isr/web/render/utilities/JavaRendererUtilities.ts +484 -0
- package/src/main/ts/armyc2/c5isr/web/render/utilities/LineInfo.ts +62 -0
- package/src/main/ts/armyc2/c5isr/web/render/utilities/SymbolInfo.ts +46 -0
- package/src/main/ts/armyc2/c5isr/web/render/utilities/TextInfo.ts +51 -0
- package/src/main/ts/org/gavaghan/geodesy/Angle.ts +31 -0
- package/src/main/ts/org/gavaghan/geodesy/Ellipsoid.ts +71 -0
- package/src/main/ts/org/gavaghan/geodesy/GeodeticCalculator.ts +200 -0
- package/src/main/ts/org/gavaghan/geodesy/GeodeticCurve.ts +55 -0
- package/src/main/ts/org/gavaghan/geodesy/GeodeticMeasurement.ts +68 -0
- package/src/main/ts/org/gavaghan/geodesy/GlobalCoordinates.ts +103 -0
- package/src/main/ts/org/gavaghan/geodesy/GlobalPosition.ts +90 -0
- package/test/ExportSPImages.js +692 -0
- package/test/MPWW.html +556 -0
- package/test/MPWorker.js +318 -0
- package/test/SPWorker.js +233 -0
- package/test/SVGWW.html +363 -0
- package/test/singlePointTester3.html +751 -0
- package/tsconfig.json +54 -0
- package/typedoc.json +30 -0
- package/updateVersion.js +21 -0
- package/webpack.config.js +34 -0
- package/webpackn.config.js +28 -0
- package/webpackr.config.js +47 -0
- package/webpackw.config.js +23 -0
|
@@ -0,0 +1,3798 @@
|
|
|
1
|
+
import { POINT2 } from "../../JavaLineArray/POINT2";
|
|
2
|
+
import { TGLight } from "../../JavaTacticalRenderer/TGLight";
|
|
3
|
+
import { clsRenderer } from "../../RenderMultipoints/clsRenderer";
|
|
4
|
+
import { AffineTransform } from "../../graphics2d/AffineTransform";
|
|
5
|
+
import { BasicStroke } from "../../graphics2d/BasicStroke";
|
|
6
|
+
import { Font } from "../../graphics2d/Font";
|
|
7
|
+
import { Point2D } from "../../graphics2d/Point2D";
|
|
8
|
+
import { Rectangle } from "../../graphics2d/Rectangle";
|
|
9
|
+
import { Rectangle2D } from "../../graphics2d/Rectangle2D";
|
|
10
|
+
import { Color } from "../../renderer/utilities/Color";
|
|
11
|
+
import { DistanceUnit } from "../../renderer/utilities/DistanceUnit";
|
|
12
|
+
import { DrawRules } from "../../renderer/utilities/DrawRules";
|
|
13
|
+
import { ErrorLogger } from "../../renderer/utilities/ErrorLogger";
|
|
14
|
+
import { GENCLookup } from "../../renderer/utilities/GENCLookup";
|
|
15
|
+
import { IPointConversion } from "../../renderer/utilities/IPointConversion";
|
|
16
|
+
import { LogLevel } from "../../renderer/utilities/LogLevel";
|
|
17
|
+
import { MSInfo } from "../../renderer/utilities/MSInfo";
|
|
18
|
+
import { MSLookup } from "../../renderer/utilities/MSLookup";
|
|
19
|
+
import { MilStdAttributes } from "../../renderer/utilities/MilStdAttributes";
|
|
20
|
+
import { MilStdSymbol } from "../../renderer/utilities/MilStdSymbol";
|
|
21
|
+
import { Modifiers } from "../../renderer/utilities/Modifiers";
|
|
22
|
+
import { PointConversion } from "../../renderer/utilities/PointConversion";
|
|
23
|
+
import { RendererSettings } from "../../renderer/utilities/RendererSettings";
|
|
24
|
+
import { RendererUtilities } from "../../renderer/utilities/RendererUtilities";
|
|
25
|
+
import { ShapeInfo } from "../../renderer/utilities/ShapeInfo";
|
|
26
|
+
import { SymbolID } from "../../renderer/utilities/SymbolID";
|
|
27
|
+
import { SymbolUtilities } from "../../renderer/utilities/SymbolUtilities";
|
|
28
|
+
import { GeoPixelConversion } from "./GeoPixelConversion";
|
|
29
|
+
import { PointConverter } from "./PointConverter";
|
|
30
|
+
import { JavaRendererUtilities } from "./utilities/JavaRendererUtilities";
|
|
31
|
+
import { LineInfo } from "./utilities/LineInfo";
|
|
32
|
+
import { SymbolInfo } from "./utilities/SymbolInfo";
|
|
33
|
+
import { TextInfo } from "./utilities/TextInfo";
|
|
34
|
+
import { mdlGeodesic } from "../../JavaTacticalRenderer/mdlGeodesic";
|
|
35
|
+
import { MultiPointHandlerSVG } from "./MultiPointHandlerSVG";
|
|
36
|
+
import { WebRenderer } from "./WebRenderer";
|
|
37
|
+
|
|
38
|
+
import { type int, type double } from "../../graphics2d/BasicTypes";
|
|
39
|
+
|
|
40
|
+
export class MultiPointHandler {
|
|
41
|
+
private static readonly _maxPixelWidth: int = 1920;
|
|
42
|
+
private static readonly _minPixelWidth: int = 720;
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* GE has the unusual distinction of being an application with coordinates
|
|
48
|
+
* outside its own extents. It appears to only be a problem when lines cross
|
|
49
|
+
* the IDL
|
|
50
|
+
*
|
|
51
|
+
* @param pts2d the client points
|
|
52
|
+
*/
|
|
53
|
+
public static NormalizeGECoordsToGEExtents(leftLongitude: double,
|
|
54
|
+
rightLongitude: double,
|
|
55
|
+
pts2d: Array<Point2D>): void {
|
|
56
|
+
try {
|
|
57
|
+
let j: int = 0;
|
|
58
|
+
let x: double = 0;
|
|
59
|
+
let y: double = 0;
|
|
60
|
+
let pt2d: Point2D;
|
|
61
|
+
let n: int = pts2d.length;
|
|
62
|
+
//for (j = 0; j < pts2d.length; j++)
|
|
63
|
+
for (j = 0; j < n; j++) {
|
|
64
|
+
pt2d = pts2d[j];
|
|
65
|
+
x = pt2d.getX();
|
|
66
|
+
y = pt2d.getY();
|
|
67
|
+
while (x < leftLongitude) {
|
|
68
|
+
x += 360;
|
|
69
|
+
}
|
|
70
|
+
while (x > rightLongitude) {
|
|
71
|
+
x -= 360;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
pt2d = new Point2D(x, y);
|
|
75
|
+
pts2d[j] = pt2d;
|
|
76
|
+
}
|
|
77
|
+
} catch (exc) {
|
|
78
|
+
if (exc instanceof Error) {
|
|
79
|
+
} else {
|
|
80
|
+
throw exc;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* GE recognizes coordinates in the range of -180 to +180
|
|
87
|
+
*
|
|
88
|
+
* @param pt2d
|
|
89
|
+
* @return
|
|
90
|
+
*/
|
|
91
|
+
static NormalizeCoordToGECoord(pt2d: Point2D): Point2D {
|
|
92
|
+
let ptGeo: Point2D;
|
|
93
|
+
try {
|
|
94
|
+
let x: double = pt2d.getX();
|
|
95
|
+
let y: double = pt2d.getY();
|
|
96
|
+
while (x < -180) {
|
|
97
|
+
x += 360;
|
|
98
|
+
}
|
|
99
|
+
while (x > 180) {
|
|
100
|
+
x -= 360;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
ptGeo = new Point2D(x, y);
|
|
104
|
+
} catch (exc) {
|
|
105
|
+
if (exc instanceof Error) {
|
|
106
|
+
} else {
|
|
107
|
+
throw exc;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return ptGeo;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* We have to ensure the bounding rectangle at least includes the symbol or
|
|
115
|
+
* there are problems rendering, especially when the symbol crosses the IDL
|
|
116
|
+
*
|
|
117
|
+
* @param controlPoints the client symbol anchor points
|
|
118
|
+
* @param bbox the original bounding box
|
|
119
|
+
* @return the modified bounding box
|
|
120
|
+
*/
|
|
121
|
+
private static getBoundingRectangle(controlPoints: string,
|
|
122
|
+
bbox: string): string {
|
|
123
|
+
let bbox2: string = "";
|
|
124
|
+
try {
|
|
125
|
+
//first get the minimum bounding rect for the geo coords
|
|
126
|
+
let left: number = 0.0;
|
|
127
|
+
let right: number = 0.0;
|
|
128
|
+
let top: number = 0.0;
|
|
129
|
+
let bottom: number = 0.0;
|
|
130
|
+
|
|
131
|
+
let coordinates: string[] = controlPoints.split(" ");
|
|
132
|
+
let len: int = coordinates.length;
|
|
133
|
+
let i: int = 0;
|
|
134
|
+
left = Number.MAX_VALUE;
|
|
135
|
+
right = -Number.MAX_VALUE;
|
|
136
|
+
top = -Number.MAX_VALUE;
|
|
137
|
+
bottom = Number.MAX_VALUE;
|
|
138
|
+
for (i = 0; i < len; i++) {
|
|
139
|
+
let coordPair: string[] = coordinates[i].split(",");
|
|
140
|
+
let latitude: number = parseFloat(coordPair[1].trim());
|
|
141
|
+
let longitude: number = parseFloat(coordPair[0].trim());
|
|
142
|
+
if (longitude < left) {
|
|
143
|
+
left = longitude;
|
|
144
|
+
}
|
|
145
|
+
if (longitude > right) {
|
|
146
|
+
right = longitude;
|
|
147
|
+
}
|
|
148
|
+
if (latitude > top) {
|
|
149
|
+
top = latitude;
|
|
150
|
+
}
|
|
151
|
+
if (latitude < bottom) {
|
|
152
|
+
bottom = latitude;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
bbox2 = left.toString() + "," + bottom.toString() + "," + right.toString() + "," + top.toString();
|
|
156
|
+
} catch (ex) {
|
|
157
|
+
if (ex instanceof Error) {
|
|
158
|
+
console.log("Failed to create bounding rectangle in MultiPointHandler.getBoundingRect");
|
|
159
|
+
} else {
|
|
160
|
+
throw ex;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return bbox2;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* need to use the symbol to get the upper left control point in order to
|
|
168
|
+
* produce a valid PointConverter
|
|
169
|
+
*
|
|
170
|
+
* @param geoCoords
|
|
171
|
+
* @return
|
|
172
|
+
*/
|
|
173
|
+
private static getControlPoint(geoCoords: Array<Point2D>): Point2D {
|
|
174
|
+
let pt2d: Point2D;
|
|
175
|
+
try {
|
|
176
|
+
let left: double = Number.MAX_VALUE;
|
|
177
|
+
let right: double = -Number.MAX_VALUE;
|
|
178
|
+
let top: double = -Number.MAX_VALUE;
|
|
179
|
+
let bottom: double = Number.MAX_VALUE;
|
|
180
|
+
let ptTemp: Point2D;
|
|
181
|
+
let n: int = geoCoords.length;
|
|
182
|
+
//for (int j = 0; j < geoCoords.length; j++)
|
|
183
|
+
for (let j: int = 0; j < n; j++) {
|
|
184
|
+
ptTemp = geoCoords[j];
|
|
185
|
+
if (ptTemp.getX() < left) {
|
|
186
|
+
left = ptTemp.getX();
|
|
187
|
+
}
|
|
188
|
+
if (ptTemp.getX() > right) {
|
|
189
|
+
right = ptTemp.getX();
|
|
190
|
+
}
|
|
191
|
+
if (ptTemp.getY() > top) {
|
|
192
|
+
top = ptTemp.getY();
|
|
193
|
+
}
|
|
194
|
+
if (ptTemp.getY() < bottom) {
|
|
195
|
+
bottom = ptTemp.getY();
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
pt2d = new Point2D(left, top);
|
|
199
|
+
} catch (ex) {
|
|
200
|
+
if (ex instanceof Error) {
|
|
201
|
+
console.log("Failed to create control point in MultiPointHandler.getControlPoint");
|
|
202
|
+
} else {
|
|
203
|
+
throw ex;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return pt2d;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Assumes a reference in which the north pole is on top.
|
|
211
|
+
*
|
|
212
|
+
* @param geoCoords the geographic coordinates
|
|
213
|
+
* @return the upper left corner of the MBR containing the geographic
|
|
214
|
+
* coordinates
|
|
215
|
+
*/
|
|
216
|
+
private static getGeoUL(geoCoords: Array<Point2D>): Point2D {
|
|
217
|
+
let ptGeo: Point2D;
|
|
218
|
+
try {
|
|
219
|
+
let j: int = 0;
|
|
220
|
+
let pt: Point2D;
|
|
221
|
+
let left: double = geoCoords[0].getX();
|
|
222
|
+
let top: double = geoCoords[0].getY();
|
|
223
|
+
let right: double = geoCoords[0].getX();
|
|
224
|
+
let bottom: double = geoCoords[0].getY();
|
|
225
|
+
let n: int = geoCoords.length;
|
|
226
|
+
//for (j = 1; j < geoCoords.length; j++)
|
|
227
|
+
for (j = 1; j < n; j++) {
|
|
228
|
+
pt = geoCoords[j];
|
|
229
|
+
if (pt.getX() < left) {
|
|
230
|
+
left = pt.getX();
|
|
231
|
+
}
|
|
232
|
+
if (pt.getX() > right) {
|
|
233
|
+
right = pt.getX();
|
|
234
|
+
}
|
|
235
|
+
if (pt.getY() > top) {
|
|
236
|
+
top = pt.getY();
|
|
237
|
+
}
|
|
238
|
+
if (pt.getY() < bottom) {
|
|
239
|
+
bottom = pt.getY();
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
//if geoCoords crosses the IDL
|
|
243
|
+
if (right - left > 180) {
|
|
244
|
+
//There must be at least one x value on either side of +/-180. Also, there is at least
|
|
245
|
+
//one positive value to the left of +/-180 and negative x value to the right of +/-180.
|
|
246
|
+
//We are using the orientation with the north pole on top so we can keep
|
|
247
|
+
//the existing value for top. Then the left value will be the least positive x value
|
|
248
|
+
//left = geoCoords[0].getX();
|
|
249
|
+
left = 180;
|
|
250
|
+
//for (j = 1; j < geoCoords.length; j++)
|
|
251
|
+
n = geoCoords.length;
|
|
252
|
+
for (j = 0; j < n; j++) {
|
|
253
|
+
pt = geoCoords[j];
|
|
254
|
+
if (pt.getX() > 0 && pt.getX() < left) {
|
|
255
|
+
left = pt.getX();
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
ptGeo = new Point2D(left, top);
|
|
260
|
+
} catch (ex) {
|
|
261
|
+
if (ex instanceof Error) {
|
|
262
|
+
console.log("Failed to create control point in MultiPointHandler.getControlPoint");
|
|
263
|
+
} else {
|
|
264
|
+
throw ex;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return ptGeo;
|
|
268
|
+
}
|
|
269
|
+
private static getBboxFromCoords(geoCoords: Array<Point2D>): string {
|
|
270
|
+
//var ptGeo = null;
|
|
271
|
+
let bbox: string;
|
|
272
|
+
try {
|
|
273
|
+
let j: int = 0;
|
|
274
|
+
let pt: Point2D;
|
|
275
|
+
let left: double = geoCoords[0].getX();
|
|
276
|
+
let top: double = geoCoords[0].getY();
|
|
277
|
+
let right: double = geoCoords[0].getX();
|
|
278
|
+
let bottom: double = geoCoords[0].getY();
|
|
279
|
+
for (j = 1; j < geoCoords.length; j++) {
|
|
280
|
+
pt = geoCoords[j];
|
|
281
|
+
if (pt.getX() < left) {
|
|
282
|
+
left = pt.getX();
|
|
283
|
+
}
|
|
284
|
+
if (pt.getX() > right) {
|
|
285
|
+
right = pt.getX();
|
|
286
|
+
}
|
|
287
|
+
if (pt.getY() > top) {
|
|
288
|
+
top = pt.getY();
|
|
289
|
+
}
|
|
290
|
+
if (pt.getY() < bottom) {
|
|
291
|
+
bottom = pt.getY();
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
//if geoCoords crosses the IDL
|
|
295
|
+
if (right - left > 180) {
|
|
296
|
+
//There must be at least one x value on either side of +/-180. Also, there is at least
|
|
297
|
+
//one positive value to the left of +/-180 and negative x value to the right of +/-180.
|
|
298
|
+
//We are using the orientation with the north pole on top so we can keep
|
|
299
|
+
//the existing value for top. Then the left value will be the least positive x value
|
|
300
|
+
//left = geoCoords[0].x;
|
|
301
|
+
left = 180;
|
|
302
|
+
right = -180;
|
|
303
|
+
for (j = 0; j < geoCoords.length; j++) {
|
|
304
|
+
pt = geoCoords[j];
|
|
305
|
+
if (pt.getX() > 0 && pt.getX() < left) {
|
|
306
|
+
left = pt.getX();
|
|
307
|
+
}
|
|
308
|
+
if (pt.getX() < 0 && pt.getX() > right) {
|
|
309
|
+
right = pt.getX();
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
//ptGeo = new Point2D(left, top);
|
|
314
|
+
bbox = left.toString() + "," + bottom.toString() + "," + right.toString() + "," + top.toString();
|
|
315
|
+
} catch (ex) {
|
|
316
|
+
if (ex instanceof Error) {
|
|
317
|
+
console.log("Failed to create control point in MultiPointHandler.getBboxFromCoords");
|
|
318
|
+
} else {
|
|
319
|
+
throw ex;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
//return ptGeo;
|
|
323
|
+
return bbox;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
private static crossesIDL(geoCoords: Array<Point2D>): boolean {
|
|
327
|
+
let result: boolean = false;
|
|
328
|
+
let pt2d: Point2D = MultiPointHandler.getControlPoint(geoCoords);
|
|
329
|
+
let left: double = pt2d.getX();
|
|
330
|
+
let ptTemp: Point2D;
|
|
331
|
+
let n: int = geoCoords.length;
|
|
332
|
+
//for (int j = 0; j < geoCoords.length; j++)
|
|
333
|
+
for (let j: int = 0; j < n; j++) {
|
|
334
|
+
ptTemp = geoCoords[j];
|
|
335
|
+
if (Math.abs(ptTemp.getX() - left) > 180) {
|
|
336
|
+
return true;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return result;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Checks if a symbol is one with decorated lines which puts a strain on
|
|
344
|
+
* google earth when rendering like FLOT. These complicated lines should be
|
|
345
|
+
* clipped when possible.
|
|
346
|
+
*
|
|
347
|
+
* @param symbolID
|
|
348
|
+
* @return
|
|
349
|
+
*/
|
|
350
|
+
public static ShouldClipSymbol(symbolID: string): boolean {
|
|
351
|
+
//TODO: need to reevaluate this function to make sure we clip the right symbols.
|
|
352
|
+
let status: int = SymbolID.getStatus(symbolID);
|
|
353
|
+
|
|
354
|
+
if (SymbolUtilities.isTacticalGraphic(symbolID) && status === SymbolID.Status_Planned_Anticipated_Suspect) {
|
|
355
|
+
return true;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
if (SymbolUtilities.isWeather(symbolID)) {
|
|
359
|
+
return true;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
let id: int = parseInt(SymbolUtilities.getBasicSymbolID(symbolID));
|
|
363
|
+
//TODO: needs to be reworked
|
|
364
|
+
if (id === 25341100 || //Task Fix
|
|
365
|
+
id === 25260200 || //CFL
|
|
366
|
+
id === 25110100 || //Boundary
|
|
367
|
+
id === 25110200 || //Light Line (LL)
|
|
368
|
+
id === 25110300 || //Engineer Work Line (EWL)
|
|
369
|
+
id === 25140100 || //FLOT
|
|
370
|
+
id === 25140200 || //Line of contact is now just two flots, but APP6 still has it as a separate symbol
|
|
371
|
+
id === 25151000 || //Fortified Area
|
|
372
|
+
id === 25151100 || //Limited Access Area
|
|
373
|
+
id === 25172000 || //Weapons Free Zone
|
|
374
|
+
id === 25151202 || //Battle Position/Prepared but not Occupied
|
|
375
|
+
id === 25151203 || //Strong Point
|
|
376
|
+
id === 25141200 || //Probable Line of Deployment (PLD)
|
|
377
|
+
id === 25270800 || //Mined Area
|
|
378
|
+
id === 25270801 || //Mined Area, Fenced
|
|
379
|
+
id === 25170100 || //Air Corridor
|
|
380
|
+
id === 25170200 || //Low Level Transit Route (LLTR)
|
|
381
|
+
id === 25170300 || //Minimum-Risk Route (MRR)
|
|
382
|
+
id === 25170400 || //Safe Lane (SL)
|
|
383
|
+
id === 25170500 || //Standard Use ARmy Aircraft Flight Route (SAAFR)
|
|
384
|
+
id === 25170600 || //Transit Corridors (TC)
|
|
385
|
+
id === 25170700 || //Special Corridor (SC)
|
|
386
|
+
|
|
387
|
+
id === 25270100 || //Obstacle Belt
|
|
388
|
+
id === 25270200 || //Obstacle Zone
|
|
389
|
+
id === 25270300 || //Obstacle Free Zone
|
|
390
|
+
id === 25270400 || //Obstacle Restricted Zone
|
|
391
|
+
|
|
392
|
+
id === 25290100 || //Obstacle Line
|
|
393
|
+
id === 25290201 || //Antitank Ditch - Under Construction
|
|
394
|
+
id === 25290202 || //Antitank Ditch - Completed
|
|
395
|
+
id === 25290203 || //Antitank Ditch Reinforced, with Antitank Mines
|
|
396
|
+
id === 25290204 || //Antitank Wall
|
|
397
|
+
id === 25290301 || //Unspecified
|
|
398
|
+
id === 25290302 || //Single Fence
|
|
399
|
+
id === 25290303 || //Double Fence
|
|
400
|
+
id === 25290304 || //Double Apron Fence
|
|
401
|
+
id === 25290305 || //Low Wire Fence
|
|
402
|
+
id === 25290306 || //High Wire Fence
|
|
403
|
+
id === 25290307 || //Single Concertina
|
|
404
|
+
id === 25290308 || //Double Strand Concertina
|
|
405
|
+
id === 25290309 || //Triple Strand Concertina
|
|
406
|
+
|
|
407
|
+
id === 25341100 || //Obstacles Effect Fix now Mission Tasks Fix
|
|
408
|
+
id === 25290400 || //Mine Cluster
|
|
409
|
+
id === 25282003 || //Aviation / Overhead Wire
|
|
410
|
+
id === 25270602 || //Bypass Difficult
|
|
411
|
+
id === 25271500 || //Ford Easy
|
|
412
|
+
id === 25271600 || //Ford Difficult
|
|
413
|
+
|
|
414
|
+
id === 25290900 || //Fortified Line
|
|
415
|
+
|
|
416
|
+
id === 25271700 || //Biological Contaminated Area
|
|
417
|
+
id === 25271800 || //Chemical Contaminated Area
|
|
418
|
+
id === 25271900 || //Nuclear Contaminated Area
|
|
419
|
+
id === 25272000 || //Radiological Contaminated Area
|
|
420
|
+
|
|
421
|
+
id === 25240301 || //No Fire Area (NFA) - Irregular
|
|
422
|
+
id === 25240302 || //No Fire Area (NFA) - Rectangular
|
|
423
|
+
id === 25240303 || //No Fire Area (NFA) - Circular
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
id === 25240701 || //Linear Target
|
|
427
|
+
id === 25240702 || //Linear Smoke Target
|
|
428
|
+
id === 25240703 || //Final Protective Fire (FPF)
|
|
429
|
+
id === 25151800 || //Encirclement
|
|
430
|
+
|
|
431
|
+
id === 25330300 || //MSR
|
|
432
|
+
id === 25330301 || //MSR / One Way Traffic
|
|
433
|
+
id === 25330302 || //MSR / Two Way Traffic
|
|
434
|
+
id === 25330303 || //MSR / Alternating Traffic
|
|
435
|
+
|
|
436
|
+
id === 25330400 || //ASR
|
|
437
|
+
id === 25330401 || //ASR / One Way Traffic
|
|
438
|
+
id === 25330402 || //ASR / Two Way Traffic
|
|
439
|
+
id === 25330403 || //AMSR / Alternating Traffic
|
|
440
|
+
|
|
441
|
+
id === 25151205 || //Retain
|
|
442
|
+
id === 25341500 || //Isolate
|
|
443
|
+
|
|
444
|
+
id === 25340600 || //counterattack.
|
|
445
|
+
id === 25340700 || //counterattack by fire.
|
|
446
|
+
//id == G*G*PA----****X || //AoA for Feint - appears to be gone in 2525D
|
|
447
|
+
id === 25271200 || //Blown Bridges Planned
|
|
448
|
+
id === 25271202 || //Blown Bridges Explosives, State of Readiness 1 (Safe)
|
|
449
|
+
id === 25341200) // Follow and Assume
|
|
450
|
+
{
|
|
451
|
+
return true;
|
|
452
|
+
} else {
|
|
453
|
+
return false;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Assumes bbox is of form left,bottom,right,top and it is currently only
|
|
459
|
+
* using the width to calculate a reasonable scale. If the original scale is
|
|
460
|
+
* within the max and min range it returns the original scale.
|
|
461
|
+
*
|
|
462
|
+
* @param bbox
|
|
463
|
+
* @param origScale
|
|
464
|
+
* @return
|
|
465
|
+
*/
|
|
466
|
+
private static getReasonableScale(bbox: string, origScale: double): double {
|
|
467
|
+
try {
|
|
468
|
+
let bounds: string[] = bbox.split(",");
|
|
469
|
+
let left: double = parseFloat(bounds[0]);
|
|
470
|
+
let right: double = parseFloat(bounds[2]);
|
|
471
|
+
let top: double = parseFloat(bounds[3]);
|
|
472
|
+
let bottom: double = parseFloat(bounds[1]);
|
|
473
|
+
|
|
474
|
+
let ul: POINT2 = new POINT2(left, top);
|
|
475
|
+
let ur: POINT2 = new POINT2(right, top);
|
|
476
|
+
|
|
477
|
+
let widthInMeters: double = 0;
|
|
478
|
+
if ((left === -180 && right === 180) || (left === 180 && right === -180)) {
|
|
479
|
+
|
|
480
|
+
widthInMeters = 40075017 / 2;
|
|
481
|
+
}
|
|
482
|
+
// Earth's circumference / 2
|
|
483
|
+
else {
|
|
484
|
+
|
|
485
|
+
widthInMeters = mdlGeodesic.geodesic_distance(ul, ur, null, null);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
let minScale: double = widthInMeters / (MultiPointHandler._maxPixelWidth as double / RendererSettings.getInstance().getDeviceDPI() / GeoPixelConversion.INCHES_PER_METER);
|
|
490
|
+
if (origScale < minScale) {
|
|
491
|
+
return minScale;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
let maxScale: double = widthInMeters / (MultiPointHandler._minPixelWidth as double / RendererSettings.getInstance().getDeviceDPI() / GeoPixelConversion.INCHES_PER_METER);
|
|
495
|
+
if (origScale > maxScale) {
|
|
496
|
+
return maxScale;
|
|
497
|
+
}
|
|
498
|
+
} catch (ignored) {
|
|
499
|
+
}
|
|
500
|
+
return origScale;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
*
|
|
505
|
+
* @param id
|
|
506
|
+
* @param name
|
|
507
|
+
* @param description
|
|
508
|
+
* @param symbolCode
|
|
509
|
+
* @param controlPoints
|
|
510
|
+
* @param scale
|
|
511
|
+
* @param bbox
|
|
512
|
+
* @param symbolModifiers {@link Map}, keyed using constants from
|
|
513
|
+
* Modifiers. Pass in comma delimited String for modifiers with multiple
|
|
514
|
+
* values like AM, AN & X
|
|
515
|
+
* @param symbolAttributes {@link Map}, keyed using constants from
|
|
516
|
+
* MilStdAttributes. pass in double[] for AM, AN and X; Strings for the
|
|
517
|
+
* rest.
|
|
518
|
+
* @param format
|
|
519
|
+
* @return
|
|
520
|
+
*/
|
|
521
|
+
public static RenderSymbol(id: string,
|
|
522
|
+
name: string,
|
|
523
|
+
description: string,
|
|
524
|
+
symbolCode: string,
|
|
525
|
+
controlPoints: string,
|
|
526
|
+
scale: number,
|
|
527
|
+
bbox: string,
|
|
528
|
+
symbolModifiers: Map<string, string>,
|
|
529
|
+
symbolAttributes: Map<string, string>,
|
|
530
|
+
format: int): string//,
|
|
531
|
+
{
|
|
532
|
+
//console.log("MultiPointHandler.RenderSymbol()");
|
|
533
|
+
let normalize: boolean = true;
|
|
534
|
+
//Double controlLat = 0.0;
|
|
535
|
+
//Double controlLong = 0.0;
|
|
536
|
+
//Double metPerPix = GeoPixelConversion.metersPerPixel(scale);
|
|
537
|
+
//String bbox2=getBoundingRectangle(controlPoints,bbox);
|
|
538
|
+
let jsonOutput: string = "";
|
|
539
|
+
let jsonContent: string = "";
|
|
540
|
+
|
|
541
|
+
let rect: Rectangle;
|
|
542
|
+
let coordinates: string[] = controlPoints.split(" ");
|
|
543
|
+
let tgl: TGLight = new TGLight();
|
|
544
|
+
let shapes: Array<ShapeInfo> = new Array<ShapeInfo>();
|
|
545
|
+
let modifiers: Array<ShapeInfo> = new Array<ShapeInfo>();
|
|
546
|
+
//ArrayList<Point2D> pixels = new ArrayList<Point2D>();
|
|
547
|
+
let geoCoords: Array<Point2D> = new Array<Point2D>();
|
|
548
|
+
let len: int = coordinates.length;
|
|
549
|
+
//diagnostic create geoCoords here
|
|
550
|
+
let coordsUL: Point2D = null;
|
|
551
|
+
|
|
552
|
+
let symbolIsValid: string = MultiPointHandler.canRenderMultiPoint(symbolCode, symbolModifiers, len);
|
|
553
|
+
if (symbolIsValid !== "true") {
|
|
554
|
+
let ErrorOutput: string = "";
|
|
555
|
+
ErrorOutput += ("{\"type\":\"error\",\"error\":\"There was an error creating the MilStdSymbol " + symbolCode + " - ID: " + id + " - ");
|
|
556
|
+
ErrorOutput += symbolIsValid; //reason for error
|
|
557
|
+
ErrorOutput += ("\"}");
|
|
558
|
+
ErrorLogger.LogMessage("MultiPointHandler", "RenderSymbol", symbolIsValid, LogLevel.FINE);
|
|
559
|
+
return ErrorOutput;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
if (MSLookup.getInstance().getMSLInfo(symbolCode).getDrawRule() != DrawRules.AREA10) // AREA10 can support infinite points
|
|
563
|
+
len = Math.min(len, MSLookup.getInstance().getMSLInfo(symbolCode).getMaxPointCount());
|
|
564
|
+
for (let i: int = 0; i < len; i++) {
|
|
565
|
+
let coordPair: string[] = coordinates[i].split(",");
|
|
566
|
+
let latitude: number = parseFloat(coordPair[1].trim());
|
|
567
|
+
let longitude: number = parseFloat(coordPair[0].trim());
|
|
568
|
+
geoCoords.push(new Point2D(longitude, latitude));
|
|
569
|
+
}
|
|
570
|
+
let tgPoints: Array<POINT2>;
|
|
571
|
+
let ipc: IPointConversion;
|
|
572
|
+
|
|
573
|
+
//Deutch moved section 6-29-11
|
|
574
|
+
let left: number = 0.0;
|
|
575
|
+
let right: number = 0.0;
|
|
576
|
+
let top: number = 0.0;
|
|
577
|
+
let bottom: number = 0.0;
|
|
578
|
+
let temp: Point2D;
|
|
579
|
+
let ptGeoUL: Point2D;
|
|
580
|
+
let width: int = 0;
|
|
581
|
+
let height: int = 0;
|
|
582
|
+
let leftX: int = 0;
|
|
583
|
+
let topY: int = 0;
|
|
584
|
+
let bottomY: int = 0;
|
|
585
|
+
let rightX: int = 0;
|
|
586
|
+
let j: int = 0;
|
|
587
|
+
let bboxCoords: Array<Point2D>;
|
|
588
|
+
if (bbox != null && bbox !== "") {
|
|
589
|
+
let bounds: string[];
|
|
590
|
+
if (bbox.includes(" "))//trapezoid
|
|
591
|
+
{
|
|
592
|
+
bboxCoords = new Array<Point2D>();
|
|
593
|
+
let x: double = 0;
|
|
594
|
+
let y: double = 0;
|
|
595
|
+
let coords: string[] = bbox.split(" ");
|
|
596
|
+
let arrCoord: string[];
|
|
597
|
+
for (let coord of coords) {
|
|
598
|
+
arrCoord = coord.split(",");
|
|
599
|
+
x = parseFloat(arrCoord[0]);
|
|
600
|
+
y = parseFloat(arrCoord[1]);
|
|
601
|
+
bboxCoords.push(new Point2D(x, y));
|
|
602
|
+
}
|
|
603
|
+
//use the upper left corner of the MBR containing geoCoords
|
|
604
|
+
//to set the converter
|
|
605
|
+
ptGeoUL = MultiPointHandler.getGeoUL(bboxCoords);
|
|
606
|
+
left = ptGeoUL.getX();
|
|
607
|
+
top = ptGeoUL.getY();
|
|
608
|
+
let bbox2: string = MultiPointHandler.getBboxFromCoords(bboxCoords);
|
|
609
|
+
scale = MultiPointHandler.getReasonableScale(bbox2, scale);
|
|
610
|
+
ipc = new PointConverter(left, top, scale);
|
|
611
|
+
let ptPixels: Point2D;
|
|
612
|
+
let ptGeo: Point2D;
|
|
613
|
+
let n: int = bboxCoords.length;
|
|
614
|
+
//for (j = 0; j < bboxCoords.length; j++)
|
|
615
|
+
for (j = 0; j < n; j++) {
|
|
616
|
+
ptGeo = bboxCoords[j];
|
|
617
|
+
ptPixels = ipc.GeoToPixels(ptGeo);
|
|
618
|
+
x = ptPixels.getX();
|
|
619
|
+
y = ptPixels.getY();
|
|
620
|
+
if (x < 20) {
|
|
621
|
+
x = 20;
|
|
622
|
+
}
|
|
623
|
+
if (y < 20) {
|
|
624
|
+
y = 20;
|
|
625
|
+
}
|
|
626
|
+
ptPixels.setLocation(x, y);
|
|
627
|
+
//end section
|
|
628
|
+
bboxCoords[j] = ptPixels;
|
|
629
|
+
}
|
|
630
|
+
} else//rectangle
|
|
631
|
+
{
|
|
632
|
+
bounds = bbox.split(",");
|
|
633
|
+
left = parseFloat(bounds[0]);
|
|
634
|
+
right = parseFloat(bounds[2]);
|
|
635
|
+
top = parseFloat(bounds[3]);
|
|
636
|
+
bottom = parseFloat(bounds[1]);
|
|
637
|
+
scale = MultiPointHandler.getReasonableScale(bbox, scale);
|
|
638
|
+
ipc = new PointConverter(left, top, scale);
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
let pt2d: Point2D;
|
|
642
|
+
if (bboxCoords == null) {
|
|
643
|
+
pt2d = new Point2D(left, top);
|
|
644
|
+
temp = ipc.GeoToPixels(pt2d);
|
|
645
|
+
|
|
646
|
+
leftX = temp.getX() as int;
|
|
647
|
+
topY = temp.getY() as int;
|
|
648
|
+
|
|
649
|
+
pt2d = new Point2D(right, bottom);
|
|
650
|
+
temp = ipc.GeoToPixels(pt2d);
|
|
651
|
+
|
|
652
|
+
bottomY = temp.getY() as int;
|
|
653
|
+
rightX = temp.getX() as int;
|
|
654
|
+
//diagnostic clipping does not work at large scales
|
|
655
|
+
// if(scale>10e6)
|
|
656
|
+
// {
|
|
657
|
+
// //diagnostic replace above by using a new ipc based on the coordinates MBR
|
|
658
|
+
// coordsUL=getGeoUL(geoCoords);
|
|
659
|
+
// temp = ipc.GeoToPixels(coordsUL);
|
|
660
|
+
// left=coordsUL.getX();
|
|
661
|
+
// top=coordsUL.getY();
|
|
662
|
+
// //shift the ipc to coordsUL origin so that conversions will be more accurate for large scales.
|
|
663
|
+
// ipc = new PointConverter(left, top, scale);
|
|
664
|
+
// //shift the rect to compenstate for the shifted ipc so that we can maintain the original clipping area.
|
|
665
|
+
// leftX -= (int)temp.getX();
|
|
666
|
+
// rightX -= (int)temp.getX();
|
|
667
|
+
// topY -= (int)temp.getY();
|
|
668
|
+
// bottomY -= (int)temp.getY();
|
|
669
|
+
// //end diagnostic
|
|
670
|
+
// }
|
|
671
|
+
//end section
|
|
672
|
+
|
|
673
|
+
width = Math.abs(rightX - leftX) as int;
|
|
674
|
+
height = Math.abs(bottomY - topY) as int;
|
|
675
|
+
|
|
676
|
+
rect = new Rectangle(leftX, topY, width, height);
|
|
677
|
+
}
|
|
678
|
+
} else {
|
|
679
|
+
rect = null;
|
|
680
|
+
}
|
|
681
|
+
//end section
|
|
682
|
+
|
|
683
|
+
// for (int i = 0; i < len; i++) {
|
|
684
|
+
// String[] coordPair = coordinates[i].split(",");
|
|
685
|
+
// Double latitude = Double.valueOf(coordPair[1].trim());
|
|
686
|
+
// Double longitude = Double.valueOf(coordPair[0].trim());
|
|
687
|
+
// geoCoords.push(new Point2D(longitude, latitude));
|
|
688
|
+
// }
|
|
689
|
+
if (ipc == null) {
|
|
690
|
+
let ptCoordsUL: Point2D = MultiPointHandler.getGeoUL(geoCoords);
|
|
691
|
+
ipc = new PointConverter(ptCoordsUL.getX(), ptCoordsUL.getY(), scale);
|
|
692
|
+
}
|
|
693
|
+
//if (crossesIDL(geoCoords) == true)
|
|
694
|
+
// if(Math.abs(right-left)>180)
|
|
695
|
+
// {
|
|
696
|
+
// normalize = true;
|
|
697
|
+
// ((PointConverter)ipc).set_normalize(true);
|
|
698
|
+
// }
|
|
699
|
+
// else {
|
|
700
|
+
// normalize = false;
|
|
701
|
+
// ((PointConverter)ipc).set_normalize(false);
|
|
702
|
+
// }
|
|
703
|
+
|
|
704
|
+
//seems to work ok at world view
|
|
705
|
+
// if (normalize) {
|
|
706
|
+
// NormalizeGECoordsToGEExtents(0, 360, geoCoords);
|
|
707
|
+
// }
|
|
708
|
+
|
|
709
|
+
//M. Deutch 10-3-11
|
|
710
|
+
//must shift the rect pixels to synch with the new ipc
|
|
711
|
+
//the old ipc was in synch with the bbox, so rect x,y was always 0,0
|
|
712
|
+
//the new ipc synchs with the upper left of the geocoords so the boox is shifted
|
|
713
|
+
//and therefore the clipping rectangle must shift by the delta x,y between
|
|
714
|
+
//the upper left corner of the original bbox and the upper left corner of the geocoords
|
|
715
|
+
let geoCoords2: Array<Point2D> = new Array<Point2D>();
|
|
716
|
+
geoCoords2.push(new Point2D(left, top));
|
|
717
|
+
geoCoords2.push(new Point2D(right, bottom));
|
|
718
|
+
|
|
719
|
+
// if (normalize) {
|
|
720
|
+
// NormalizeGECoordsToGEExtents(0, 360, geoCoords2);
|
|
721
|
+
// }
|
|
722
|
+
|
|
723
|
+
//disable clipping
|
|
724
|
+
if (MultiPointHandler.ShouldClipSymbol(symbolCode) === false) {
|
|
725
|
+
|
|
726
|
+
if (MultiPointHandler.crossesIDL(geoCoords) === false) {
|
|
727
|
+
rect = null;
|
|
728
|
+
bboxCoords = null;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
tgl.set_SymbolId(symbolCode);// "GFGPSLA---****X" AMBUSH symbol code
|
|
734
|
+
tgl.set_Pixels(null);
|
|
735
|
+
|
|
736
|
+
try {
|
|
737
|
+
|
|
738
|
+
//String fillColor = null;
|
|
739
|
+
let mSymbol: MilStdSymbol = new MilStdSymbol(symbolCode, null, geoCoords, null);
|
|
740
|
+
|
|
741
|
+
if (format == WebRenderer.OUTPUT_FORMAT_GEOSVG) {
|
|
742
|
+
// Use dash array and hatch pattern fill for SVG output
|
|
743
|
+
symbolAttributes.set(MilStdAttributes.UseDashArray, 'true')
|
|
744
|
+
symbolAttributes.set(MilStdAttributes.UsePatternFill, "true")
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
if (symbolModifiers != null || symbolAttributes != null) {
|
|
748
|
+
MultiPointHandler.populateModifiers(symbolModifiers, symbolAttributes, mSymbol);
|
|
749
|
+
} else {
|
|
750
|
+
mSymbol.setFillColor(null);
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
if (bboxCoords == null) {
|
|
754
|
+
clsRenderer.renderWithPolylines(mSymbol, ipc, rect);
|
|
755
|
+
} else {
|
|
756
|
+
clsRenderer.renderWithPolylines(mSymbol, ipc, bboxCoords);
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
shapes = mSymbol.getSymbolShapes();
|
|
760
|
+
modifiers = mSymbol.getModifierShapes();
|
|
761
|
+
|
|
762
|
+
if (format === WebRenderer.OUTPUT_FORMAT_JSON) {
|
|
763
|
+
jsonOutput += ("{\"type\":\"symbol\",");
|
|
764
|
+
jsonContent = MultiPointHandler.JSONize(shapes, modifiers, ipc, true, normalize);
|
|
765
|
+
jsonOutput += (jsonContent);
|
|
766
|
+
jsonOutput += ("}");
|
|
767
|
+
} else if (format === WebRenderer.OUTPUT_FORMAT_KML) {
|
|
768
|
+
var textColor = mSymbol.getTextColor();
|
|
769
|
+
if(textColor==null)
|
|
770
|
+
textColor=mSymbol.getLineColor();
|
|
771
|
+
|
|
772
|
+
jsonContent = MultiPointHandler.KMLize(id, name, description, symbolCode, shapes, modifiers, ipc, normalize, textColor);
|
|
773
|
+
jsonOutput += jsonContent;
|
|
774
|
+
} else if (format === WebRenderer.OUTPUT_FORMAT_GEOJSON) {
|
|
775
|
+
/*
|
|
776
|
+
jsonOutput += ("{\"type\":\"FeatureCollection\",\"features\":");
|
|
777
|
+
jsonContent = GeoJSONize(shapes, modifiers, ipc, normalize, mSymbol.getTextColor(), mSymbol.getTextBackgroundColor());
|
|
778
|
+
jsonOutput += (jsonContent);
|
|
779
|
+
jsonOutput += (",\"properties\":{\"id\":\"");
|
|
780
|
+
jsonOutput += (id);
|
|
781
|
+
jsonOutput += ("\",\"name\":\"");
|
|
782
|
+
jsonOutput += (name);
|
|
783
|
+
jsonOutput += ("\",\"description\":\"");
|
|
784
|
+
jsonOutput += (description);
|
|
785
|
+
jsonOutput += ("\",\"symbolID\":\"");
|
|
786
|
+
jsonOutput += (symbolCode);
|
|
787
|
+
jsonOutput += ("\",\"wasClipped\":\"");
|
|
788
|
+
jsonOutput += (mSymbol.get_WasClipped()).toString();
|
|
789
|
+
jsonOutput += ("\"}}"); */
|
|
790
|
+
|
|
791
|
+
jsonOutput += ("{\"type\":\"FeatureCollection\",\"features\":");
|
|
792
|
+
jsonContent = MultiPointHandler.GeoJSONize(shapes, modifiers, ipc, normalize, mSymbol.getTextColor(), mSymbol.getTextBackgroundColor());
|
|
793
|
+
jsonOutput += (jsonContent);
|
|
794
|
+
|
|
795
|
+
//moving meta data properties to the last feature with no coords as feature collection doesn't allow properties
|
|
796
|
+
jsonOutput = jsonOutput.slice(0, -1);
|
|
797
|
+
jsonOutput += (",{\"type\": \"Feature\",\"geometry\": { \"type\": \"Polygon\",\"coordinates\": [ ]}");
|
|
798
|
+
|
|
799
|
+
jsonOutput += (",\"properties\":{\"id\":\"");
|
|
800
|
+
jsonOutput += (id);
|
|
801
|
+
jsonOutput += ("\",\"name\":\"");
|
|
802
|
+
jsonOutput += (name);
|
|
803
|
+
jsonOutput += ("\",\"description\":\"");
|
|
804
|
+
jsonOutput += (description);
|
|
805
|
+
jsonOutput += ("\",\"symbolID\":\"");
|
|
806
|
+
jsonOutput += (symbolCode);
|
|
807
|
+
jsonOutput += ("\",\"wasClipped\":\"");
|
|
808
|
+
jsonOutput += (mSymbol.get_WasClipped()).toString();
|
|
809
|
+
//jsonOutput += ("\"}}");
|
|
810
|
+
|
|
811
|
+
jsonOutput += ("\"}}]}");
|
|
812
|
+
} else if (format === WebRenderer.OUTPUT_FORMAT_GEOSVG) {
|
|
813
|
+
let textColor = mSymbol.getTextColor() ? mSymbol.getTextColor().toHexString(false) : "";
|
|
814
|
+
let backgroundColor = mSymbol.getTextBackgroundColor() ? mSymbol.getTextBackgroundColor().toHexString(false) : "";
|
|
815
|
+
//returns an svg with a geoTL and geoBR value to use to place the canvas on the map
|
|
816
|
+
jsonOutput = MultiPointHandlerSVG.GeoSVGize(id, name, description, symbolCode, shapes, modifiers, ipc, normalize, textColor, backgroundColor, mSymbol.get_WasClipped());
|
|
817
|
+
}
|
|
818
|
+
} catch (exc) {
|
|
819
|
+
if (exc instanceof Error) {
|
|
820
|
+
let st: string = JavaRendererUtilities.getStackTrace(exc);
|
|
821
|
+
jsonOutput = "";
|
|
822
|
+
jsonOutput += ("{\"type\":\"error\",\"error\":\"There was an error creating the MilStdSymbol " + symbolCode + ": " + "- ");
|
|
823
|
+
jsonOutput += (exc.message + " - ");
|
|
824
|
+
jsonOutput += (st);
|
|
825
|
+
jsonOutput += ("\"}");
|
|
826
|
+
|
|
827
|
+
ErrorLogger.LogException("MultiPointHandler", "RenderSymbol", exc);
|
|
828
|
+
} else {
|
|
829
|
+
throw exc;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
/*
|
|
834
|
+
let debug: boolean = false;
|
|
835
|
+
if (debug === true) {
|
|
836
|
+
console.log("Symbol Code: " + symbolCode);
|
|
837
|
+
console.log("Scale: " + scale);
|
|
838
|
+
console.log("BBOX: " + bbox);
|
|
839
|
+
if (controlPoints != null) {
|
|
840
|
+
console.log("Geo Points: " + controlPoints);
|
|
841
|
+
}
|
|
842
|
+
if (tgl != null && tgl.get_Pixels() != null)//pixels != null
|
|
843
|
+
{
|
|
844
|
+
console.log("Pixel: " + tgl.get_Pixels().toString());
|
|
845
|
+
}
|
|
846
|
+
if (bbox != null) {
|
|
847
|
+
console.log("geo bounds: " + bbox);
|
|
848
|
+
}
|
|
849
|
+
if (rect != null) {
|
|
850
|
+
console.log("pixel bounds: " + rect.toString());
|
|
851
|
+
}
|
|
852
|
+
if (jsonOutput != null) {
|
|
853
|
+
console.log(jsonOutput.toString());
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
*/
|
|
857
|
+
|
|
858
|
+
ErrorLogger.LogMessage("MultiPointHandler", "RenderSymbol()", "exit RenderSymbol", LogLevel.FINER);
|
|
859
|
+
return jsonOutput.toString();
|
|
860
|
+
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
/**
|
|
864
|
+
*
|
|
865
|
+
* @param id
|
|
866
|
+
* @param name
|
|
867
|
+
* @param description
|
|
868
|
+
* @param symbolCode
|
|
869
|
+
* @param controlPoints
|
|
870
|
+
* @param scale
|
|
871
|
+
* @param bbox
|
|
872
|
+
* @param symbolModifiers
|
|
873
|
+
* @param symbolAttributes
|
|
874
|
+
* @return
|
|
875
|
+
*/
|
|
876
|
+
public static RenderSymbolAsMilStdSymbol(id: string,
|
|
877
|
+
name: string,
|
|
878
|
+
description: string,
|
|
879
|
+
symbolCode: string,
|
|
880
|
+
controlPoints: string,
|
|
881
|
+
scale: number,
|
|
882
|
+
bbox: string,
|
|
883
|
+
symbolModifiers: Map<string, string>,
|
|
884
|
+
symbolAttributes: Map<string, string>): MilStdSymbol//,
|
|
885
|
+
//ArrayList<ShapeInfo>shapes)
|
|
886
|
+
{
|
|
887
|
+
let mSymbol: MilStdSymbol;
|
|
888
|
+
//console.log("MultiPointHandler.RenderSymbol()");
|
|
889
|
+
let normalize: boolean = true;
|
|
890
|
+
let controlLat: number = 0.0;
|
|
891
|
+
let controlLong: number = 0.0;
|
|
892
|
+
//String jsonContent = "";
|
|
893
|
+
|
|
894
|
+
let rect: Rectangle;
|
|
895
|
+
|
|
896
|
+
//for symbol & line fill
|
|
897
|
+
let tgPoints: Array<POINT2>;
|
|
898
|
+
|
|
899
|
+
let coordinates: string[] = controlPoints.split(" ");
|
|
900
|
+
let tgl: TGLight = new TGLight();
|
|
901
|
+
let shapes: Array<ShapeInfo>;//new ArrayList<ShapeInfo>();
|
|
902
|
+
let modifiers: Array<ShapeInfo>;//new ArrayList<ShapeInfo>();
|
|
903
|
+
//ArrayList<Point2D> pixels = new ArrayList<Point2D>();
|
|
904
|
+
let geoCoords: Array<Point2D> = new Array<Point2D>();
|
|
905
|
+
let len: int = coordinates.length;
|
|
906
|
+
|
|
907
|
+
let ipc: IPointConversion;
|
|
908
|
+
|
|
909
|
+
//Deutch moved section 6-29-11
|
|
910
|
+
let left: number = 0.0;
|
|
911
|
+
let right: number = 0.0;
|
|
912
|
+
let top: number = 0.0;
|
|
913
|
+
let bottom: number = 0.0;
|
|
914
|
+
let temp: Point2D;
|
|
915
|
+
let ptGeoUL: Point2D;
|
|
916
|
+
let width: int = 0;
|
|
917
|
+
let height: int = 0;
|
|
918
|
+
let leftX: int = 0;
|
|
919
|
+
let topY: int = 0;
|
|
920
|
+
let bottomY: int = 0;
|
|
921
|
+
let rightX: int = 0;
|
|
922
|
+
let j: int = 0;
|
|
923
|
+
let bboxCoords: Array<Point2D>;
|
|
924
|
+
if (bbox != null && bbox !== "") {
|
|
925
|
+
let bounds: string[];
|
|
926
|
+
if (bbox.includes(" "))//trapezoid
|
|
927
|
+
{
|
|
928
|
+
bboxCoords = new Array<Point2D>();
|
|
929
|
+
let x: double = 0;
|
|
930
|
+
let y: double = 0;
|
|
931
|
+
let coords: string[] = bbox.split(" ");
|
|
932
|
+
let arrCoord: string[];
|
|
933
|
+
for (let coord of coords) {
|
|
934
|
+
arrCoord = coord.split(",");
|
|
935
|
+
x = parseFloat(arrCoord[0]);
|
|
936
|
+
y = parseFloat(arrCoord[1]);
|
|
937
|
+
bboxCoords.push(new Point2D(x, y));
|
|
938
|
+
}
|
|
939
|
+
//use the upper left corner of the MBR containing geoCoords
|
|
940
|
+
//to set the converter
|
|
941
|
+
ptGeoUL = MultiPointHandler.getGeoUL(bboxCoords);
|
|
942
|
+
left = ptGeoUL.getX();
|
|
943
|
+
top = ptGeoUL.getY();
|
|
944
|
+
ipc = new PointConverter(left, top, scale);
|
|
945
|
+
let ptPixels: Point2D;
|
|
946
|
+
let ptGeo: Point2D;
|
|
947
|
+
let n: int = bboxCoords.length;
|
|
948
|
+
//for (j = 0; j < bboxCoords.length; j++)
|
|
949
|
+
for (j = 0; j < n; j++) {
|
|
950
|
+
ptGeo = bboxCoords[j];
|
|
951
|
+
ptPixels = ipc.GeoToPixels(ptGeo);
|
|
952
|
+
x = ptPixels.getX();
|
|
953
|
+
y = ptPixels.getY();
|
|
954
|
+
if (x < 20) {
|
|
955
|
+
x = 20;
|
|
956
|
+
}
|
|
957
|
+
if (y < 20) {
|
|
958
|
+
y = 20;
|
|
959
|
+
}
|
|
960
|
+
ptPixels.setLocation(x, y);
|
|
961
|
+
//end section
|
|
962
|
+
bboxCoords[j] = ptPixels;
|
|
963
|
+
}
|
|
964
|
+
} else//rectangle
|
|
965
|
+
{
|
|
966
|
+
bounds = bbox.split(",");
|
|
967
|
+
left = parseFloat(bounds[0]);
|
|
968
|
+
right = parseFloat(bounds[2]);
|
|
969
|
+
top = parseFloat(bounds[3]);
|
|
970
|
+
bottom = parseFloat(bounds[1]);
|
|
971
|
+
scale = MultiPointHandler.getReasonableScale(bbox, scale);
|
|
972
|
+
ipc = new PointConverter(left, top, scale);
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
let pt2d: Point2D;
|
|
976
|
+
if (bboxCoords == null) {
|
|
977
|
+
pt2d = new Point2D(left, top);
|
|
978
|
+
temp = ipc.GeoToPixels(pt2d);
|
|
979
|
+
|
|
980
|
+
leftX = temp.getX() as int;
|
|
981
|
+
topY = temp.getY() as int;
|
|
982
|
+
|
|
983
|
+
pt2d = new Point2D(right, bottom);
|
|
984
|
+
temp = ipc.GeoToPixels(pt2d);
|
|
985
|
+
|
|
986
|
+
bottomY = temp.getY() as int;
|
|
987
|
+
rightX = temp.getX() as int;
|
|
988
|
+
//diagnostic clipping does not work for large scales
|
|
989
|
+
// if (scale > 10e6) {
|
|
990
|
+
// //get widest point in the AOI
|
|
991
|
+
// double midLat = 0;
|
|
992
|
+
// if (bottom < 0 && top > 0) {
|
|
993
|
+
// midLat = 0;
|
|
994
|
+
// } else if (bottom < 0 && top < 0) {
|
|
995
|
+
// midLat = top;
|
|
996
|
+
// } else if (bottom > 0 && top > 0) {
|
|
997
|
+
// midLat = bottom;
|
|
998
|
+
// }
|
|
999
|
+
//
|
|
1000
|
+
// temp = ipc.GeoToPixels(new Point2D(right, midLat));
|
|
1001
|
+
// rightX = (int) temp.getX();
|
|
1002
|
+
// }
|
|
1003
|
+
//end section
|
|
1004
|
+
|
|
1005
|
+
width = Math.abs(rightX - leftX) as int;
|
|
1006
|
+
height = Math.abs(bottomY - topY) as int;
|
|
1007
|
+
|
|
1008
|
+
if (width === 0 || height === 0) {
|
|
1009
|
+
|
|
1010
|
+
rect = null;
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
else {
|
|
1014
|
+
|
|
1015
|
+
rect = new Rectangle(leftX, topY, width, height);
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
}
|
|
1019
|
+
} else {
|
|
1020
|
+
rect = null;
|
|
1021
|
+
}
|
|
1022
|
+
//end section
|
|
1023
|
+
|
|
1024
|
+
//check for required points & parameters
|
|
1025
|
+
let symbolIsValid: string = MultiPointHandler.canRenderMultiPoint(symbolCode, symbolModifiers, len);
|
|
1026
|
+
if (symbolIsValid !== "true") {
|
|
1027
|
+
ErrorLogger.LogMessage("MultiPointHandler", "RenderSymbolAsMilStdSymbol", symbolIsValid, LogLevel.WARNING);
|
|
1028
|
+
return mSymbol;
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
if (MSLookup.getInstance().getMSLInfo(symbolCode).getDrawRule() != DrawRules.AREA10) // AREA10 can support infinite points
|
|
1032
|
+
len = Math.min(len, MSLookup.getInstance().getMSLInfo(symbolCode).getMaxPointCount());
|
|
1033
|
+
for (let i: int = 0; i < len; i++) {
|
|
1034
|
+
let coordPair: string[] = coordinates[i].split(",");
|
|
1035
|
+
let latitude: number = parseFloat(coordPair[1].trim());
|
|
1036
|
+
let longitude: number = parseFloat(coordPair[0].trim());
|
|
1037
|
+
geoCoords.push(new Point2D(longitude, latitude));
|
|
1038
|
+
}
|
|
1039
|
+
if (ipc == null) {
|
|
1040
|
+
let ptCoordsUL: Point2D = MultiPointHandler.getGeoUL(geoCoords);
|
|
1041
|
+
ipc = new PointConverter(ptCoordsUL.getX(), ptCoordsUL.getY(), scale);
|
|
1042
|
+
}
|
|
1043
|
+
//if (crossesIDL(geoCoords) == true)
|
|
1044
|
+
// if(Math.abs(right-left)>180)
|
|
1045
|
+
// {
|
|
1046
|
+
// normalize = true;
|
|
1047
|
+
// ((PointConverter)ipc).set_normalize(true);
|
|
1048
|
+
// }
|
|
1049
|
+
// else {
|
|
1050
|
+
// normalize = false;
|
|
1051
|
+
// ((PointConverter)ipc).set_normalize(false);
|
|
1052
|
+
// }
|
|
1053
|
+
|
|
1054
|
+
//seems to work ok at world view
|
|
1055
|
+
// if (normalize) {
|
|
1056
|
+
// NormalizeGECoordsToGEExtents(0, 360, geoCoords);
|
|
1057
|
+
// }
|
|
1058
|
+
|
|
1059
|
+
//M. Deutch 10-3-11
|
|
1060
|
+
//must shift the rect pixels to synch with the new ipc
|
|
1061
|
+
//the old ipc was in synch with the bbox, so rect x,y was always 0,0
|
|
1062
|
+
//the new ipc synchs with the upper left of the geocoords so the boox is shifted
|
|
1063
|
+
//and therefore the clipping rectangle must shift by the delta x,y between
|
|
1064
|
+
//the upper left corner of the original bbox and the upper left corner of the geocoords
|
|
1065
|
+
let geoCoords2: Array<Point2D> = new Array<Point2D>();
|
|
1066
|
+
geoCoords2.push(new Point2D(left, top));
|
|
1067
|
+
geoCoords2.push(new Point2D(right, bottom));
|
|
1068
|
+
|
|
1069
|
+
// if (normalize) {
|
|
1070
|
+
// NormalizeGECoordsToGEExtents(0, 360, geoCoords2);
|
|
1071
|
+
// }
|
|
1072
|
+
|
|
1073
|
+
//disable clipping
|
|
1074
|
+
if (MultiPointHandler.ShouldClipSymbol(symbolCode) === false) {
|
|
1075
|
+
|
|
1076
|
+
if (MultiPointHandler.crossesIDL(geoCoords) === false) {
|
|
1077
|
+
rect = null;
|
|
1078
|
+
bboxCoords = null;
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
tgl.set_SymbolId(symbolCode);// "GFGPSLA---****X" AMBUSH symbol code
|
|
1083
|
+
tgl.set_Pixels(null);
|
|
1084
|
+
|
|
1085
|
+
try {
|
|
1086
|
+
|
|
1087
|
+
let fillColor: string;
|
|
1088
|
+
mSymbol = new MilStdSymbol(symbolCode, null, geoCoords, null);
|
|
1089
|
+
|
|
1090
|
+
// mSymbol.setUseDashArray(true);
|
|
1091
|
+
|
|
1092
|
+
if (symbolModifiers != null || symbolAttributes != null) {
|
|
1093
|
+
MultiPointHandler.populateModifiers(symbolModifiers, symbolAttributes, mSymbol);
|
|
1094
|
+
} else {
|
|
1095
|
+
mSymbol.setFillColor(null);
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
if (mSymbol.getFillColor() != null) {
|
|
1099
|
+
let fc: Color = mSymbol.getFillColor();
|
|
1100
|
+
fillColor = RendererUtilities.colorToHexString(fc, false);
|
|
1101
|
+
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
if (bboxCoords == null) {
|
|
1105
|
+
clsRenderer.renderWithPolylines(mSymbol, ipc, rect);
|
|
1106
|
+
} else {
|
|
1107
|
+
clsRenderer.renderWithPolylines(mSymbol, ipc, bboxCoords);
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
shapes = mSymbol.getSymbolShapes();
|
|
1111
|
+
modifiers = mSymbol.getModifierShapes();
|
|
1112
|
+
|
|
1113
|
+
//convert points////////////////////////////////////////////////////
|
|
1114
|
+
let polylines: Array<Array<Point2D>>;
|
|
1115
|
+
let newPolylines: Array<Array<Point2D>>;
|
|
1116
|
+
let newLine: Array<Point2D>;
|
|
1117
|
+
for (let shape of shapes) {
|
|
1118
|
+
polylines = shape.getPolylines();
|
|
1119
|
+
//console.log("pixel polylines: " + polylines.toString());
|
|
1120
|
+
newPolylines = MultiPointHandler.ConvertPolylinePixelsToCoords(polylines, ipc, normalize);
|
|
1121
|
+
shape.setPolylines(newPolylines);
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
for (let label of modifiers) {
|
|
1125
|
+
let pixelCoord: Point2D = label.getModifierPosition();
|
|
1126
|
+
if (pixelCoord == null) {
|
|
1127
|
+
pixelCoord = label.getGlyphPosition();
|
|
1128
|
+
}
|
|
1129
|
+
let geoCoord: Point2D = ipc.PixelsToGeo(pixelCoord);
|
|
1130
|
+
|
|
1131
|
+
if (normalize) {
|
|
1132
|
+
geoCoord = MultiPointHandler.NormalizeCoordToGECoord(geoCoord);
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
let latitude: double = geoCoord.getY();
|
|
1136
|
+
let longitude: double = geoCoord.getX();
|
|
1137
|
+
label.setModifierPosition(new Point2D(longitude, latitude));
|
|
1138
|
+
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
////////////////////////////////////////////////////////////////////
|
|
1142
|
+
mSymbol.setModifierShapes(modifiers);
|
|
1143
|
+
mSymbol.setSymbolShapes(shapes);
|
|
1144
|
+
|
|
1145
|
+
} catch (exc) {
|
|
1146
|
+
if (exc instanceof Error) {
|
|
1147
|
+
console.log(exc.message);
|
|
1148
|
+
console.log("Symbol Code: " + symbolCode);
|
|
1149
|
+
console.log(exc.stack);
|
|
1150
|
+
} else {
|
|
1151
|
+
throw exc;
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
/*
|
|
1156
|
+
let debug: boolean = false;
|
|
1157
|
+
if (debug === true) {
|
|
1158
|
+
console.log("Symbol Code: " + symbolCode);
|
|
1159
|
+
console.log("Scale: " + scale);
|
|
1160
|
+
console.log("BBOX: " + bbox);
|
|
1161
|
+
if (controlPoints != null) {
|
|
1162
|
+
console.log("Geo Points: " + controlPoints);
|
|
1163
|
+
}
|
|
1164
|
+
if (tgl != null && tgl.get_Pixels() != null)//pixels != null
|
|
1165
|
+
{
|
|
1166
|
+
//console.log("Pixel: " + pixels.toString());
|
|
1167
|
+
console.log("Pixel: " + tgl.get_Pixels().toString());
|
|
1168
|
+
}
|
|
1169
|
+
if (bbox != null) {
|
|
1170
|
+
console.log("geo bounds: " + bbox);
|
|
1171
|
+
}
|
|
1172
|
+
if (rect != null) {
|
|
1173
|
+
console.log("pixel bounds: " + rect.toString());
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
*/
|
|
1177
|
+
|
|
1178
|
+
return mSymbol;
|
|
1179
|
+
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
private static ConvertPolylinePixelsToCoords(polylines: Array<Array<Point2D>>, ipc: IPointConversion, normalize: boolean): Array<Array<Point2D>> {
|
|
1183
|
+
let newPolylines: Array<Array<Point2D>> = new Array<Array<Point2D>>();
|
|
1184
|
+
|
|
1185
|
+
let latitude: double = 0;
|
|
1186
|
+
let longitude: double = 0;
|
|
1187
|
+
let newLine: Array<Point2D>;
|
|
1188
|
+
try {
|
|
1189
|
+
for (let line of polylines) {
|
|
1190
|
+
newLine = new Array<Point2D>();
|
|
1191
|
+
for (let pt of line) {
|
|
1192
|
+
let geoCoord: Point2D = ipc.PixelsToGeo(pt);
|
|
1193
|
+
|
|
1194
|
+
if (normalize) {
|
|
1195
|
+
geoCoord = MultiPointHandler.NormalizeCoordToGECoord(geoCoord);
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
latitude = geoCoord.getY();
|
|
1199
|
+
longitude = geoCoord.getX();
|
|
1200
|
+
newLine.push(new Point2D(longitude, latitude));
|
|
1201
|
+
}
|
|
1202
|
+
newPolylines.push(newLine);
|
|
1203
|
+
}
|
|
1204
|
+
} catch (exc) {
|
|
1205
|
+
if (exc instanceof Error) {
|
|
1206
|
+
console.log(exc.message);
|
|
1207
|
+
console.log(exc.stack);
|
|
1208
|
+
} else {
|
|
1209
|
+
throw exc;
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
return newPolylines;
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
/**
|
|
1216
|
+
* Multipoint Rendering on flat 2D maps
|
|
1217
|
+
*
|
|
1218
|
+
* @param id A unique ID for the symbol. only used in KML currently
|
|
1219
|
+
* @param name
|
|
1220
|
+
* @param description
|
|
1221
|
+
* @param symbolCode
|
|
1222
|
+
* @param controlPoints
|
|
1223
|
+
* @param pixelWidth pixel dimensions of the viewable map area
|
|
1224
|
+
* @param pixelHeight pixel dimensions of the viewable map area
|
|
1225
|
+
* @param bbox The viewable area of the map. Passed in the format of a
|
|
1226
|
+
* string "lowerLeftX,lowerLeftY,upperRightX,upperRightY." example:
|
|
1227
|
+
* "-50.4,23.6,-42.2,24.2"
|
|
1228
|
+
* @param symbolModifiers Modifier with multiple values should be comma
|
|
1229
|
+
* delimited
|
|
1230
|
+
* @param symbolAttributes
|
|
1231
|
+
* @param format An enumeration: 0 for KML, 1 for JSON.
|
|
1232
|
+
* @return A JSON or KML string representation of the graphic.
|
|
1233
|
+
*/
|
|
1234
|
+
public static RenderSymbol2D(id: string,
|
|
1235
|
+
name: string,
|
|
1236
|
+
description: string,
|
|
1237
|
+
symbolCode: string,
|
|
1238
|
+
controlPoints: string,
|
|
1239
|
+
pixelWidth: int,
|
|
1240
|
+
pixelHeight: int,
|
|
1241
|
+
bbox: string,
|
|
1242
|
+
symbolModifiers: Map<string, string>,
|
|
1243
|
+
symbolAttributes: Map<string, string>,
|
|
1244
|
+
format: int): string {
|
|
1245
|
+
let jsonOutput: string = "";
|
|
1246
|
+
let jsonContent: string = "";
|
|
1247
|
+
|
|
1248
|
+
let rect: Rectangle;
|
|
1249
|
+
|
|
1250
|
+
let tgPoints: Array<POINT2>;
|
|
1251
|
+
|
|
1252
|
+
let coordinates: string[] = controlPoints.split(" ");
|
|
1253
|
+
let tgl: TGLight = new TGLight();
|
|
1254
|
+
let shapes: Array<ShapeInfo> = new Array<ShapeInfo>();
|
|
1255
|
+
let modifiers: Array<ShapeInfo> = new Array<ShapeInfo>();
|
|
1256
|
+
let geoCoords: Array<Point2D> = new Array<Point2D>();
|
|
1257
|
+
let len: int = coordinates.length;
|
|
1258
|
+
let ipc: IPointConversion;
|
|
1259
|
+
|
|
1260
|
+
//check for required points & parameters
|
|
1261
|
+
let symbolIsValid: string = MultiPointHandler.canRenderMultiPoint(symbolCode, symbolModifiers, len);
|
|
1262
|
+
if (symbolIsValid !== "true") {
|
|
1263
|
+
let ErrorOutput: string = "";
|
|
1264
|
+
ErrorOutput += ("{\"type\":\"error\",\"error\":\"There was an error creating the MilStdSymbol " + symbolCode + " - ID: " + id + " - ");
|
|
1265
|
+
ErrorOutput += symbolIsValid; //reason for error
|
|
1266
|
+
ErrorOutput += ("\"}");
|
|
1267
|
+
ErrorLogger.LogMessage("MultiPointHandler", "RenderSymbol2D", symbolIsValid, LogLevel.FINE);
|
|
1268
|
+
return ErrorOutput;
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
let left: number = 0.0;
|
|
1272
|
+
let right: number = 0.0;
|
|
1273
|
+
let top: number = 0.0;
|
|
1274
|
+
let bottom: number = 0.0;
|
|
1275
|
+
if (bbox != null && bbox !== "") {
|
|
1276
|
+
let bounds: string[] = bbox.split(",");
|
|
1277
|
+
|
|
1278
|
+
left = parseFloat(bounds[0]);
|
|
1279
|
+
right = parseFloat(bounds[2]);
|
|
1280
|
+
top = parseFloat(bounds[3]);
|
|
1281
|
+
bottom = parseFloat(bounds[1]);
|
|
1282
|
+
|
|
1283
|
+
ipc = new PointConversion(pixelWidth, pixelHeight, top, left, bottom, right);
|
|
1284
|
+
} else {
|
|
1285
|
+
console.log("Bad bbox value: " + bbox);
|
|
1286
|
+
console.log("bbox is viewable area of the map. Passed in the format of a string \"lowerLeftX,lowerLeftY,upperRightX,upperRightY.\" example: \"-50.4,23.6,-42.2,24.2\"");
|
|
1287
|
+
return "ERROR - Bad bbox value: " + bbox;
|
|
1288
|
+
}
|
|
1289
|
+
//end section
|
|
1290
|
+
|
|
1291
|
+
//get coordinates
|
|
1292
|
+
if (MSLookup.getInstance().getMSLInfo(symbolCode).getDrawRule() != DrawRules.AREA10) // AREA10 can support infinite points
|
|
1293
|
+
len = Math.min(len, MSLookup.getInstance().getMSLInfo(symbolCode).getMaxPointCount());
|
|
1294
|
+
for (let i: int = 0; i < len; i++) {
|
|
1295
|
+
let coordPair: string[] = coordinates[i].split(",");
|
|
1296
|
+
let latitude: number = parseFloat(coordPair[1].trim());
|
|
1297
|
+
let longitude: number = parseFloat(coordPair[0].trim());
|
|
1298
|
+
geoCoords.push(new Point2D(longitude, latitude));
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
try {
|
|
1302
|
+
let mSymbol: MilStdSymbol = new MilStdSymbol(symbolCode, null, geoCoords, null);
|
|
1303
|
+
|
|
1304
|
+
if (format == WebRenderer.OUTPUT_FORMAT_GEOSVG) {
|
|
1305
|
+
// Use dash array and hatch pattern fill for SVG output
|
|
1306
|
+
symbolAttributes.set(MilStdAttributes.UseDashArray, 'true')
|
|
1307
|
+
symbolAttributes.set(MilStdAttributes.UsePatternFill, "true")
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
if (symbolModifiers != null && symbolModifiers.size !== 0) {
|
|
1311
|
+
MultiPointHandler.populateModifiers(symbolModifiers, symbolAttributes, mSymbol);
|
|
1312
|
+
} else {
|
|
1313
|
+
mSymbol.setFillColor(null);
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
//build clipping bounds
|
|
1317
|
+
let temp: Point2D;
|
|
1318
|
+
let leftX: int = 0;
|
|
1319
|
+
let topY: int = 0;
|
|
1320
|
+
let bottomY: int = 0;
|
|
1321
|
+
let rightX: int = 0;
|
|
1322
|
+
let width: int = 0;
|
|
1323
|
+
let height: int = 0;
|
|
1324
|
+
let normalize: boolean = false;
|
|
1325
|
+
// if(Math.abs(right-left)>180)
|
|
1326
|
+
// {
|
|
1327
|
+
// ((PointConversion)ipc).set_normalize(true);
|
|
1328
|
+
// normalize=true;
|
|
1329
|
+
// }
|
|
1330
|
+
// else
|
|
1331
|
+
// {
|
|
1332
|
+
// ((PointConversion)ipc).set_normalize(false);
|
|
1333
|
+
// }
|
|
1334
|
+
if (MultiPointHandler.ShouldClipSymbol(symbolCode) || MultiPointHandler.crossesIDL(geoCoords)) {
|
|
1335
|
+
let lt: Point2D = new Point2D(left, top);
|
|
1336
|
+
//temp = ipc.GeoToPixels(new Point2D(left, top));
|
|
1337
|
+
temp = ipc.GeoToPixels(lt);
|
|
1338
|
+
leftX = temp.getX() as int;
|
|
1339
|
+
topY = temp.getY() as int;
|
|
1340
|
+
|
|
1341
|
+
let rb: Point2D = new Point2D(right, bottom);
|
|
1342
|
+
//temp = ipc.GeoToPixels(new Point2D(right, bottom));
|
|
1343
|
+
temp = ipc.GeoToPixels(rb);
|
|
1344
|
+
bottomY = temp.getY() as int;
|
|
1345
|
+
rightX = temp.getX() as int;
|
|
1346
|
+
//////////////////
|
|
1347
|
+
|
|
1348
|
+
width = Math.abs(rightX - leftX) as int;
|
|
1349
|
+
height = Math.abs(bottomY - topY) as int;
|
|
1350
|
+
|
|
1351
|
+
rect = new Rectangle(leftX, topY, width, height);
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
//new interface
|
|
1355
|
+
//IMultiPointRenderer mpr = MultiPointRenderer.getInstance();
|
|
1356
|
+
clsRenderer.renderWithPolylines(mSymbol, ipc, rect);
|
|
1357
|
+
shapes = mSymbol.getSymbolShapes();
|
|
1358
|
+
modifiers = mSymbol.getModifierShapes();
|
|
1359
|
+
|
|
1360
|
+
//boolean normalize = false;
|
|
1361
|
+
|
|
1362
|
+
if (format === WebRenderer.OUTPUT_FORMAT_JSON) {
|
|
1363
|
+
jsonOutput += ("{\"type\":\"symbol\",");
|
|
1364
|
+
//jsonContent = JSONize(shapes, modifiers, ipc, normalize);
|
|
1365
|
+
jsonOutput += (jsonContent);
|
|
1366
|
+
jsonOutput += ("}");
|
|
1367
|
+
} else if (format === WebRenderer.OUTPUT_FORMAT_KML) {
|
|
1368
|
+
var textColor = mSymbol.getTextColor();
|
|
1369
|
+
if(textColor==null)
|
|
1370
|
+
textColor=mSymbol.getLineColor();
|
|
1371
|
+
|
|
1372
|
+
jsonContent = MultiPointHandler.KMLize(id, name, description, symbolCode, shapes, modifiers, ipc, normalize, textColor);
|
|
1373
|
+
jsonOutput += jsonContent;
|
|
1374
|
+
} else if (format === WebRenderer.OUTPUT_FORMAT_GEOJSON) {
|
|
1375
|
+
jsonOutput += ("{\"type\":\"FeatureCollection\",\"features\":");
|
|
1376
|
+
jsonContent = MultiPointHandler.GeoJSONize(shapes, modifiers, ipc, normalize, mSymbol.getTextColor(), mSymbol.getTextBackgroundColor());
|
|
1377
|
+
jsonOutput += (jsonContent);
|
|
1378
|
+
|
|
1379
|
+
//moving meta data properties to the last feature with no coords as feature collection doesn't allow properties
|
|
1380
|
+
jsonOutput = jsonOutput.slice(0, -1);
|
|
1381
|
+
jsonOutput += (",{\"type\": \"Feature\",\"geometry\": { \"type\": \"Polygon\",\"coordinates\": [ ]}");
|
|
1382
|
+
|
|
1383
|
+
jsonOutput += (",\"properties\":{\"id\":\"");
|
|
1384
|
+
jsonOutput += (id);
|
|
1385
|
+
jsonOutput += ("\",\"name\":\"");
|
|
1386
|
+
jsonOutput += (name);
|
|
1387
|
+
jsonOutput += ("\",\"description\":\"");
|
|
1388
|
+
jsonOutput += (description);
|
|
1389
|
+
jsonOutput += ("\",\"symbolID\":\"");
|
|
1390
|
+
jsonOutput += (symbolCode);
|
|
1391
|
+
jsonOutput += ("\",\"wasClipped\":\"");
|
|
1392
|
+
jsonOutput += (mSymbol.get_WasClipped()).toString();
|
|
1393
|
+
//jsonOutput += ("\"}}");
|
|
1394
|
+
|
|
1395
|
+
jsonOutput += ("\"}}]}");
|
|
1396
|
+
|
|
1397
|
+
} else if (format === WebRenderer.OUTPUT_FORMAT_GEOSVG) {
|
|
1398
|
+
let textColor = mSymbol.getTextColor() ? mSymbol.getTextColor().toHexString(false) : "";
|
|
1399
|
+
let backgroundColor = mSymbol.getTextBackgroundColor() ? mSymbol.getTextBackgroundColor().toHexString(false) : "";
|
|
1400
|
+
//returns an svg with a geoTL and geoBR value to use to place the canvas on the map
|
|
1401
|
+
jsonOutput = MultiPointHandlerSVG.GeoSVGize(id, name, description, symbolCode, shapes, modifiers, ipc, normalize, textColor, backgroundColor, mSymbol.get_WasClipped());
|
|
1402
|
+
}
|
|
1403
|
+
} catch (exc) {
|
|
1404
|
+
if (exc instanceof Error) {
|
|
1405
|
+
jsonOutput = "";
|
|
1406
|
+
jsonOutput += ("{\"type\":\"error\",\"error\":\"There was an error creating the MilStdSymbol " + symbolCode + ": " + "- ");
|
|
1407
|
+
jsonOutput += (exc.message + " - ");
|
|
1408
|
+
jsonOutput += (ErrorLogger.getStackTrace(exc));
|
|
1409
|
+
jsonOutput += ("\"}");
|
|
1410
|
+
} else {
|
|
1411
|
+
throw exc;
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1415
|
+
/*
|
|
1416
|
+
let debug: boolean = false;
|
|
1417
|
+
if (debug === true) {
|
|
1418
|
+
console.log("Symbol Code: " + symbolCode);
|
|
1419
|
+
console.log("BBOX: " + bbox);
|
|
1420
|
+
if (controlPoints != null) {
|
|
1421
|
+
console.log("Geo Points: " + controlPoints);
|
|
1422
|
+
}
|
|
1423
|
+
if (tgl != null && tgl.get_Pixels() != null)//pixels != null
|
|
1424
|
+
{
|
|
1425
|
+
//console.log("Pixel: " + pixels.toString());
|
|
1426
|
+
console.log("Pixel: " + tgl.get_Pixels().toString());
|
|
1427
|
+
}
|
|
1428
|
+
if (bbox != null) {
|
|
1429
|
+
console.log("geo bounds: " + bbox);
|
|
1430
|
+
}
|
|
1431
|
+
if (rect != null) {
|
|
1432
|
+
console.log("pixel bounds: " + rect.toString());
|
|
1433
|
+
}
|
|
1434
|
+
if (jsonOutput != null) {
|
|
1435
|
+
console.log(jsonOutput.toString());
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
*/
|
|
1439
|
+
|
|
1440
|
+
return jsonOutput.toString();
|
|
1441
|
+
|
|
1442
|
+
}
|
|
1443
|
+
|
|
1444
|
+
/**
|
|
1445
|
+
* For Mike Deutch testing
|
|
1446
|
+
*
|
|
1447
|
+
* @param id
|
|
1448
|
+
* @param name
|
|
1449
|
+
* @param description
|
|
1450
|
+
* @param symbolCode
|
|
1451
|
+
* @param controlPoints
|
|
1452
|
+
* @param pixelWidth
|
|
1453
|
+
* @param pixelHeight
|
|
1454
|
+
* @param bbox
|
|
1455
|
+
* @param symbolModifiers
|
|
1456
|
+
* @param shapes
|
|
1457
|
+
* @param modifiers
|
|
1458
|
+
* @param format
|
|
1459
|
+
* @return
|
|
1460
|
+
* @deprecated
|
|
1461
|
+
*/
|
|
1462
|
+
public static RenderSymbol2DX(id: string,
|
|
1463
|
+
name: string,
|
|
1464
|
+
description: string,
|
|
1465
|
+
symbolCode: string,
|
|
1466
|
+
controlPoints: string,
|
|
1467
|
+
pixelWidth: int,
|
|
1468
|
+
pixelHeight: int,
|
|
1469
|
+
bbox: string,
|
|
1470
|
+
symbolModifiers: Map<string, string>,
|
|
1471
|
+
symbolAttributes: Map<string, string>,
|
|
1472
|
+
shapes: Array<ShapeInfo>,
|
|
1473
|
+
modifiers: Array<ShapeInfo>,
|
|
1474
|
+
format: int): string//,
|
|
1475
|
+
//ArrayList<ShapeInfo>shapes)
|
|
1476
|
+
{
|
|
1477
|
+
|
|
1478
|
+
let jsonOutput: string = "";
|
|
1479
|
+
let jsonContent: string = "";
|
|
1480
|
+
|
|
1481
|
+
let rect: Rectangle;
|
|
1482
|
+
|
|
1483
|
+
let coordinates: string[] = controlPoints.split(" ");
|
|
1484
|
+
let tgl: TGLight = new TGLight();
|
|
1485
|
+
let geoCoords: Array<Point2D> = new Array<Point2D>();
|
|
1486
|
+
let ipc: IPointConversion;
|
|
1487
|
+
|
|
1488
|
+
let left: number = 0.0;
|
|
1489
|
+
let right: number = 0.0;
|
|
1490
|
+
let top: number = 0.0;
|
|
1491
|
+
let bottom: number = 0.0;
|
|
1492
|
+
if (bbox != null && bbox !== "") {
|
|
1493
|
+
let bounds: string[] = bbox.split(",");
|
|
1494
|
+
|
|
1495
|
+
left = parseFloat(bounds[0]);
|
|
1496
|
+
right = parseFloat(bounds[2]);
|
|
1497
|
+
top = parseFloat(bounds[3]);
|
|
1498
|
+
bottom = parseFloat(bounds[1]);
|
|
1499
|
+
|
|
1500
|
+
ipc = new PointConversion(pixelWidth, pixelHeight, top, left, bottom, right);
|
|
1501
|
+
} else {
|
|
1502
|
+
console.log("Bad bbox value: " + bbox);
|
|
1503
|
+
console.log("bbox is viewable area of the map. Passed in the format of a string \"lowerLeftX,lowerLeftY,upperRightX,upperRightY.\" example: \"-50.4,23.6,-42.2,24.2\"");
|
|
1504
|
+
return "ERROR - Bad bbox value: " + bbox;
|
|
1505
|
+
}
|
|
1506
|
+
//end section
|
|
1507
|
+
|
|
1508
|
+
//get coordinates
|
|
1509
|
+
let len: int = coordinates.length;
|
|
1510
|
+
for (let i: int = 0; i < len; i++) {
|
|
1511
|
+
let coordPair: string[] = coordinates[i].split(",");
|
|
1512
|
+
let latitude: number = parseFloat(coordPair[1].trim());
|
|
1513
|
+
let longitude: number = parseFloat(coordPair[0].trim());
|
|
1514
|
+
geoCoords.push(new Point2D(longitude, latitude));
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
try {
|
|
1518
|
+
let mSymbol: MilStdSymbol = new MilStdSymbol(symbolCode, null, geoCoords, null);
|
|
1519
|
+
|
|
1520
|
+
if (symbolModifiers != null && symbolModifiers.size !== 0) {
|
|
1521
|
+
MultiPointHandler.populateModifiers(symbolModifiers, symbolAttributes, mSymbol);
|
|
1522
|
+
} else {
|
|
1523
|
+
mSymbol.setFillColor(null);
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
clsRenderer.renderWithPolylines(mSymbol, ipc, rect);
|
|
1527
|
+
shapes = mSymbol.getSymbolShapes();
|
|
1528
|
+
modifiers = mSymbol.getModifierShapes();
|
|
1529
|
+
|
|
1530
|
+
let normalize: boolean = false;
|
|
1531
|
+
|
|
1532
|
+
if (format === WebRenderer.OUTPUT_FORMAT_JSON) {
|
|
1533
|
+
jsonOutput += ("{\"type\":\"symbol\",");
|
|
1534
|
+
jsonContent = MultiPointHandler.JSONize(shapes, modifiers, ipc, false, normalize);
|
|
1535
|
+
jsonOutput += (jsonContent);
|
|
1536
|
+
jsonOutput += ("}");
|
|
1537
|
+
}
|
|
1538
|
+
} catch (exc) {
|
|
1539
|
+
if (exc instanceof Error) {
|
|
1540
|
+
jsonOutput = "";
|
|
1541
|
+
jsonOutput += ("{\"type\":\"error\",\"error\":\"There was an error creating the MilStdSymbol " + symbolCode + ": " + "- ");
|
|
1542
|
+
jsonOutput += (exc.message + " - ");
|
|
1543
|
+
jsonOutput += ("\"}");
|
|
1544
|
+
} else {
|
|
1545
|
+
throw exc;
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
let debug: boolean = true;
|
|
1550
|
+
if (debug === true) {
|
|
1551
|
+
console.log("Symbol Code: " + symbolCode);
|
|
1552
|
+
console.log("BBOX: " + bbox);
|
|
1553
|
+
if (controlPoints != null) {
|
|
1554
|
+
console.log("Geo Points: " + controlPoints);
|
|
1555
|
+
}
|
|
1556
|
+
if (tgl != null && tgl.get_Pixels() != null)//pixels != null
|
|
1557
|
+
{
|
|
1558
|
+
//console.log("Pixel: " + pixels.toString());
|
|
1559
|
+
console.log("Pixel: " + tgl.get_Pixels().toString());
|
|
1560
|
+
}
|
|
1561
|
+
if (bbox != null) {
|
|
1562
|
+
console.log("geo bounds: " + bbox);
|
|
1563
|
+
}
|
|
1564
|
+
if (rect != null) {
|
|
1565
|
+
console.log("pixel bounds: " + rect.toString());
|
|
1566
|
+
}
|
|
1567
|
+
if (jsonOutput != null) {
|
|
1568
|
+
console.log(jsonOutput.toString());
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
return jsonOutput.toString();
|
|
1572
|
+
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
private static MilStdSymbolToSymbolInfo(symbol: MilStdSymbol): SymbolInfo {
|
|
1576
|
+
let si: SymbolInfo;
|
|
1577
|
+
|
|
1578
|
+
let tiList: Array<TextInfo> = new Array<TextInfo>();
|
|
1579
|
+
let liList: Array<LineInfo> = new Array<LineInfo>();
|
|
1580
|
+
|
|
1581
|
+
let tiTemp: TextInfo;
|
|
1582
|
+
let liTemp: LineInfo;
|
|
1583
|
+
let siTemp: ShapeInfo;
|
|
1584
|
+
|
|
1585
|
+
let lines: Array<ShapeInfo> = symbol.getSymbolShapes();
|
|
1586
|
+
let modifiers: Array<ShapeInfo> = symbol.getModifierShapes();
|
|
1587
|
+
|
|
1588
|
+
let lineCount: int = lines.length;
|
|
1589
|
+
let modifierCount: int = modifiers.length;
|
|
1590
|
+
for (let i: int = 0; i < lineCount; i++) {
|
|
1591
|
+
siTemp = lines[i];
|
|
1592
|
+
if (siTemp.getPolylines() != null) {
|
|
1593
|
+
liTemp = new LineInfo();
|
|
1594
|
+
liTemp.setFillColor(siTemp.getFillColor());
|
|
1595
|
+
liTemp.setLineColor(siTemp.getLineColor());
|
|
1596
|
+
liTemp.setPolylines(siTemp.getPolylines());
|
|
1597
|
+
liTemp.setStroke(siTemp.getStroke());
|
|
1598
|
+
liList.push(liTemp);
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1602
|
+
for (let j: int = 0; j < modifierCount; j++) {
|
|
1603
|
+
tiTemp = new TextInfo();
|
|
1604
|
+
siTemp = modifiers[j];
|
|
1605
|
+
if (siTemp.getModifierString() != null) {
|
|
1606
|
+
tiTemp.setModifierString(siTemp.getModifierString());
|
|
1607
|
+
tiTemp.setModifierStringPosition(siTemp.getModifierPosition());
|
|
1608
|
+
tiTemp.setModifierStringAngle(siTemp.getModifierAngle());
|
|
1609
|
+
tiList.push(tiTemp);
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
si = new SymbolInfo(tiList, liList);
|
|
1613
|
+
return si;
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1616
|
+
/**
|
|
1617
|
+
* Populates a symbol with the modifiers from a JSON string. This function
|
|
1618
|
+
* will overwrite any previously populated modifier data.
|
|
1619
|
+
*
|
|
1620
|
+
*
|
|
1621
|
+
*
|
|
1622
|
+
* @param symbol An existing MilStdSymbol
|
|
1623
|
+
* @return
|
|
1624
|
+
*/
|
|
1625
|
+
private static populateModifiers(saModifiers: Map<string, string>, saAttributes: Map<string, string>, symbol: MilStdSymbol): boolean {
|
|
1626
|
+
let modifiers: Map<string, string> = new Map();
|
|
1627
|
+
let attributes: Map<string, string> = saAttributes;
|
|
1628
|
+
|
|
1629
|
+
// Stores array graphic modifiers for MilStdSymbol;
|
|
1630
|
+
let altitudes: Array<number> = null;
|
|
1631
|
+
let azimuths: Array<number> = null;
|
|
1632
|
+
let distances: Array<number> = null;
|
|
1633
|
+
|
|
1634
|
+
// Stores colors for symbol.
|
|
1635
|
+
let fillColor: string = null;
|
|
1636
|
+
let lineColor: string = null;
|
|
1637
|
+
let textColor: string = null;
|
|
1638
|
+
let textBackgroundColor: string = null;
|
|
1639
|
+
|
|
1640
|
+
let lineWidth: int = 0;
|
|
1641
|
+
let altMode: string = "";
|
|
1642
|
+
let useDashArray: boolean = symbol.getUseDashArray();
|
|
1643
|
+
let usePatternFill: boolean = symbol.getUseFillPattern();
|
|
1644
|
+
let patternFillType: int = 0;
|
|
1645
|
+
let hideOptionalLabels: boolean = false;
|
|
1646
|
+
let distanceUnit: DistanceUnit;
|
|
1647
|
+
let altitudeUnit: DistanceUnit;
|
|
1648
|
+
let pixelSize: int = 50;
|
|
1649
|
+
let keepUnitRatio: boolean = true;
|
|
1650
|
+
let patternScale: double = RendererSettings.getInstance().getPatternScale();
|
|
1651
|
+
|
|
1652
|
+
try {
|
|
1653
|
+
|
|
1654
|
+
// The following attirubtes are labels. All of them
|
|
1655
|
+
// are strings and can be added on the creation of the
|
|
1656
|
+
// MilStdSymbol by adding to a Map and passing in the
|
|
1657
|
+
// modifiers parameter.
|
|
1658
|
+
if (saModifiers != null) {
|
|
1659
|
+
if (saModifiers.has(Modifiers.C_QUANTITY)) {
|
|
1660
|
+
modifiers.set(Modifiers.C_QUANTITY, saModifiers.get(Modifiers.C_QUANTITY));
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
if (saModifiers.has(Modifiers.H_ADDITIONAL_INFO_1)) {
|
|
1664
|
+
modifiers.set(Modifiers.H_ADDITIONAL_INFO_1, saModifiers.get(Modifiers.H_ADDITIONAL_INFO_1));
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
if (saModifiers.has(Modifiers.H1_ADDITIONAL_INFO_2)) {
|
|
1668
|
+
modifiers.set(Modifiers.H1_ADDITIONAL_INFO_2, saModifiers.get(Modifiers.H1_ADDITIONAL_INFO_2));
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1671
|
+
if (saModifiers.has(Modifiers.H2_ADDITIONAL_INFO_3)) {
|
|
1672
|
+
modifiers.set(Modifiers.H2_ADDITIONAL_INFO_3, saModifiers.get(Modifiers.H2_ADDITIONAL_INFO_3));
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
if (saModifiers.has(Modifiers.N_HOSTILE)) {
|
|
1676
|
+
if (saModifiers.get(Modifiers.N_HOSTILE) == null) {
|
|
1677
|
+
modifiers.set(Modifiers.N_HOSTILE, "");
|
|
1678
|
+
} else {
|
|
1679
|
+
modifiers.set(Modifiers.N_HOSTILE, saModifiers.get(Modifiers.N_HOSTILE));
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
if (saModifiers.has(Modifiers.Q_DIRECTION_OF_MOVEMENT)) {
|
|
1684
|
+
modifiers.set(Modifiers.Q_DIRECTION_OF_MOVEMENT, saModifiers.get(Modifiers.Q_DIRECTION_OF_MOVEMENT));
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
if (saModifiers.has(Modifiers.T_UNIQUE_DESIGNATION_1)) {
|
|
1688
|
+
modifiers.set(Modifiers.T_UNIQUE_DESIGNATION_1, saModifiers.get(Modifiers.T_UNIQUE_DESIGNATION_1));
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1691
|
+
if (saModifiers.has(Modifiers.T1_UNIQUE_DESIGNATION_2)) {
|
|
1692
|
+
modifiers.set(Modifiers.T1_UNIQUE_DESIGNATION_2, saModifiers.get(Modifiers.T1_UNIQUE_DESIGNATION_2));
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
if (saModifiers.has(Modifiers.V_EQUIP_TYPE)) {
|
|
1696
|
+
modifiers.set(Modifiers.V_EQUIP_TYPE, saModifiers.get(Modifiers.V_EQUIP_TYPE));
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1699
|
+
if (saModifiers.has(Modifiers.AS_COUNTRY)) {
|
|
1700
|
+
modifiers.set(Modifiers.AS_COUNTRY, saModifiers.get(Modifiers.AS_COUNTRY));
|
|
1701
|
+
} else {
|
|
1702
|
+
if (SymbolID.getCountryCode(symbol.getSymbolID()) > 0 && GENCLookup.getInstance().get3CharCode(SymbolID.getCountryCode(symbol.getSymbolID())) !== "") {
|
|
1703
|
+
modifiers.set(Modifiers.AS_COUNTRY, GENCLookup.getInstance().get3CharCode(SymbolID.getCountryCode(symbol.getSymbolID())));
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
|
|
1708
|
+
if (saModifiers.has(Modifiers.AP_TARGET_NUMBER)) {
|
|
1709
|
+
modifiers.set(Modifiers.AP_TARGET_NUMBER, saModifiers.get(Modifiers.AP_TARGET_NUMBER));
|
|
1710
|
+
}
|
|
1711
|
+
|
|
1712
|
+
if (saModifiers.has(Modifiers.W_DTG_1)) {
|
|
1713
|
+
modifiers.set(Modifiers.W_DTG_1, saModifiers.get(Modifiers.W_DTG_1));
|
|
1714
|
+
}
|
|
1715
|
+
|
|
1716
|
+
if (saModifiers.has(Modifiers.W1_DTG_2)) {
|
|
1717
|
+
modifiers.set(Modifiers.W1_DTG_2, saModifiers.get(Modifiers.W1_DTG_2));
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
if (saModifiers.has(Modifiers.Y_LOCATION)) {
|
|
1721
|
+
modifiers.set(Modifiers.Y_LOCATION, saModifiers.get(Modifiers.Y_LOCATION));
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
//Required multipoint modifier arrays
|
|
1725
|
+
if (saModifiers.has(Modifiers.X_ALTITUDE_DEPTH)) {
|
|
1726
|
+
altitudes = new Array<number>();
|
|
1727
|
+
let arrAltitudes: string[] = saModifiers.get(Modifiers.X_ALTITUDE_DEPTH).split(",");
|
|
1728
|
+
for (let x of arrAltitudes) {
|
|
1729
|
+
if (x !== "") {
|
|
1730
|
+
altitudes.push(parseFloat(x));
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
|
|
1735
|
+
if (saModifiers.has(Modifiers.AM_DISTANCE)) {
|
|
1736
|
+
distances = new Array<number>();
|
|
1737
|
+
let arrDistances: string[] = saModifiers.get(Modifiers.AM_DISTANCE).split(",");
|
|
1738
|
+
for (let am of arrDistances) {
|
|
1739
|
+
if (am !== "") {
|
|
1740
|
+
distances.push(parseFloat(am));
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
|
|
1745
|
+
if (saModifiers.has(Modifiers.AN_AZIMUTH)) {
|
|
1746
|
+
azimuths = new Array<number>();
|
|
1747
|
+
let arrAzimuths: string[] = saModifiers.get(Modifiers.AN_AZIMUTH).split(",");
|
|
1748
|
+
for (let an of arrAzimuths) {
|
|
1749
|
+
if (an !== "") {
|
|
1750
|
+
azimuths.push(parseFloat(an));
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
if (saAttributes != null) {
|
|
1756
|
+
// These properties are ints, not labels, they are colors.//////////////////
|
|
1757
|
+
if (saAttributes.has(MilStdAttributes.FillColor)) {
|
|
1758
|
+
fillColor = String(saAttributes.get(MilStdAttributes.FillColor));
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
if (saAttributes.has(MilStdAttributes.LineColor)) {
|
|
1762
|
+
lineColor = String(saAttributes.get(MilStdAttributes.LineColor));
|
|
1763
|
+
}
|
|
1764
|
+
|
|
1765
|
+
if (saAttributes.has(MilStdAttributes.LineWidth)) {
|
|
1766
|
+
lineWidth = parseInt(saAttributes.get(MilStdAttributes.LineWidth));
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1769
|
+
if (saAttributes.has(MilStdAttributes.TextColor)) {
|
|
1770
|
+
textColor = String(saAttributes.get(MilStdAttributes.TextColor));
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
if (saAttributes.has(MilStdAttributes.TextBackgroundColor)) {
|
|
1774
|
+
textBackgroundColor = String(saAttributes.get(MilStdAttributes.TextBackgroundColor));
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
if (saAttributes.has(MilStdAttributes.AltitudeMode)) {
|
|
1778
|
+
altMode = saAttributes.get(MilStdAttributes.AltitudeMode);
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
if (saAttributes.has(MilStdAttributes.UseDashArray)) {
|
|
1782
|
+
useDashArray = saAttributes.get(MilStdAttributes.UseDashArray).toLowerCase() === 'true';
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1785
|
+
if (saAttributes.has(MilStdAttributes.UsePatternFill)) {
|
|
1786
|
+
usePatternFill = saAttributes.get(MilStdAttributes.UsePatternFill).toLowerCase() === 'true';
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1789
|
+
if (saAttributes.has(MilStdAttributes.PatternFillType)) {
|
|
1790
|
+
patternFillType = parseInt((saAttributes.get(MilStdAttributes.PatternFillType)));
|
|
1791
|
+
}
|
|
1792
|
+
|
|
1793
|
+
if (saAttributes.has(MilStdAttributes.HideOptionalLabels)) {
|
|
1794
|
+
hideOptionalLabels = saAttributes.get(MilStdAttributes.HideOptionalLabels).toLowerCase() === 'true';
|
|
1795
|
+
}
|
|
1796
|
+
|
|
1797
|
+
if (saAttributes.has(MilStdAttributes.AltitudeUnits)) {
|
|
1798
|
+
altitudeUnit = DistanceUnit.parse(saAttributes.get(MilStdAttributes.AltitudeUnits));
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1801
|
+
if (saAttributes.has(MilStdAttributes.DistanceUnits)) {
|
|
1802
|
+
distanceUnit = DistanceUnit.parse(saAttributes.get(MilStdAttributes.DistanceUnits));
|
|
1803
|
+
}
|
|
1804
|
+
|
|
1805
|
+
if (saAttributes.has(MilStdAttributes.PixelSize)) {
|
|
1806
|
+
pixelSize = parseInt(saAttributes.get(MilStdAttributes.PixelSize));
|
|
1807
|
+
symbol.setUnitSize(pixelSize);
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1810
|
+
if (saAttributes.has(MilStdAttributes.KeepUnitRatio)) {
|
|
1811
|
+
keepUnitRatio = saAttributes.get(MilStdAttributes.KeepUnitRatio).toLowerCase() === 'true';
|
|
1812
|
+
symbol.setKeepUnitRatio(keepUnitRatio);
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
if(saAttributes.has(MilStdAttributes.PatternScale)) {
|
|
1816
|
+
patternScale = parseFloat(saAttributes.get(MilStdAttributes.PatternScale));
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
|
|
1820
|
+
symbol.setModifierMap(modifiers);
|
|
1821
|
+
|
|
1822
|
+
if (fillColor != null && fillColor !== "") {
|
|
1823
|
+
symbol.setFillColor(RendererUtilities.getColorFromHexString(fillColor));
|
|
1824
|
+
}
|
|
1825
|
+
|
|
1826
|
+
if (lineColor != null && lineColor !== "") {
|
|
1827
|
+
symbol.setLineColor(RendererUtilities.getColorFromHexString(lineColor));
|
|
1828
|
+
symbol.setTextColor(RendererUtilities.getColorFromHexString(lineColor));
|
|
1829
|
+
}
|
|
1830
|
+
else {
|
|
1831
|
+
if (symbol.getLineColor() == null) {
|
|
1832
|
+
|
|
1833
|
+
symbol.setLineColor(Color.black);
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1838
|
+
|
|
1839
|
+
if (lineWidth > 0) {
|
|
1840
|
+
symbol.setLineWidth(lineWidth);
|
|
1841
|
+
}
|
|
1842
|
+
|
|
1843
|
+
if (textColor != null && textColor !== "") {
|
|
1844
|
+
symbol.setTextColor(RendererUtilities.getColorFromHexString(textColor));
|
|
1845
|
+
} else {
|
|
1846
|
+
if (symbol.getTextColor() == null) {
|
|
1847
|
+
|
|
1848
|
+
symbol.setTextColor(Color.black);
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
|
|
1854
|
+
if (textBackgroundColor != null && textBackgroundColor !== "") {
|
|
1855
|
+
symbol.setTextBackgroundColor(RendererUtilities.getColorFromHexString(textBackgroundColor));
|
|
1856
|
+
}
|
|
1857
|
+
|
|
1858
|
+
if (altMode != null) {
|
|
1859
|
+
symbol.setAltitudeMode(altMode);
|
|
1860
|
+
}
|
|
1861
|
+
|
|
1862
|
+
symbol.setUseDashArray(useDashArray);
|
|
1863
|
+
symbol.setUseFillPattern(usePatternFill);
|
|
1864
|
+
symbol.setHideOptionalLabels(hideOptionalLabels);
|
|
1865
|
+
symbol.setAltitudeUnit(altitudeUnit);
|
|
1866
|
+
symbol.setDistanceUnit(distanceUnit);
|
|
1867
|
+
symbol.setPatternScale(patternScale);
|
|
1868
|
+
|
|
1869
|
+
// Check grpahic modifiers variables. If we set earlier, populate
|
|
1870
|
+
// the fields, otherwise, ignore.
|
|
1871
|
+
if (altitudes != null) {
|
|
1872
|
+
symbol.setModifiers_AM_AN_X(Modifiers.X_ALTITUDE_DEPTH, altitudes);
|
|
1873
|
+
}
|
|
1874
|
+
if (distances != null) {
|
|
1875
|
+
symbol.setModifiers_AM_AN_X(Modifiers.AM_DISTANCE, distances);
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1878
|
+
if (azimuths != null) {
|
|
1879
|
+
symbol.setModifiers_AM_AN_X(Modifiers.AN_AZIMUTH, azimuths);
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
//Check if sector range fan has required min range
|
|
1883
|
+
if (SymbolUtilities.getBasicSymbolID(symbol.getSymbolID()) === "25242200") {
|
|
1884
|
+
if (symbol.getModifiers_AM_AN_X(Modifiers.AN_AZIMUTH) != null
|
|
1885
|
+
&& symbol.getModifiers_AM_AN_X(Modifiers.AM_DISTANCE) != null) {
|
|
1886
|
+
let anCount: int = symbol.getModifiers_AM_AN_X(Modifiers.AN_AZIMUTH).length;
|
|
1887
|
+
let amCount: int = symbol.getModifiers_AM_AN_X(Modifiers.AM_DISTANCE).length;
|
|
1888
|
+
let am: Array<number>;
|
|
1889
|
+
if (amCount < ((anCount / 2) + 1)) {
|
|
1890
|
+
am = symbol.getModifiers_AM_AN_X(Modifiers.AM_DISTANCE);
|
|
1891
|
+
if (am[0] !== 0.0) {
|
|
1892
|
+
am.splice(0, 0, 0.0);
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
}
|
|
1897
|
+
} catch (exc2) {
|
|
1898
|
+
if (exc2 instanceof Error) {
|
|
1899
|
+
ErrorLogger.LogException("MPH.populateModifiers", "PopulateModifiers", exc2);
|
|
1900
|
+
} else {
|
|
1901
|
+
throw exc2;
|
|
1902
|
+
}
|
|
1903
|
+
}
|
|
1904
|
+
return true;
|
|
1905
|
+
|
|
1906
|
+
}
|
|
1907
|
+
|
|
1908
|
+
private static KMLize(id: string, name: string,
|
|
1909
|
+
description: string,
|
|
1910
|
+
symbolCode: string,
|
|
1911
|
+
shapes: Array<ShapeInfo>,
|
|
1912
|
+
modifiers: Array<ShapeInfo>,
|
|
1913
|
+
ipc: IPointConversion,
|
|
1914
|
+
normalize: boolean, textColor: Color): string {
|
|
1915
|
+
|
|
1916
|
+
let kml: string = "";
|
|
1917
|
+
|
|
1918
|
+
let tempModifier: ShapeInfo;
|
|
1919
|
+
|
|
1920
|
+
let cdataStart: string = "<![CDATA[";
|
|
1921
|
+
let cdataEnd: string = "]]>";
|
|
1922
|
+
|
|
1923
|
+
let len: int = shapes.length;
|
|
1924
|
+
kml += ("<Folder id=\"" + id + "\">");
|
|
1925
|
+
kml += ("<name>" + cdataStart + name + cdataEnd + "</name>");
|
|
1926
|
+
kml += ("<visibility>1</visibility>");
|
|
1927
|
+
for (let i: int = 0; i < len; i++) {
|
|
1928
|
+
|
|
1929
|
+
let shapesToAdd: string = MultiPointHandler.ShapeToKMLString(name, description, symbolCode, shapes[i], ipc, normalize);
|
|
1930
|
+
kml += (shapesToAdd);
|
|
1931
|
+
}
|
|
1932
|
+
|
|
1933
|
+
let len2: int = modifiers.length;
|
|
1934
|
+
|
|
1935
|
+
for (let j: int = 0; j < len2; j++) {
|
|
1936
|
+
|
|
1937
|
+
tempModifier = modifiers[j];
|
|
1938
|
+
|
|
1939
|
+
//if(geMap)//if using google earth
|
|
1940
|
+
//assume kml text is going to be centered
|
|
1941
|
+
//AdjustModifierPointToCenter(tempModifier);
|
|
1942
|
+
|
|
1943
|
+
let labelsToAdd: string = MultiPointHandler.LabelToKMLString(tempModifier, ipc, normalize, textColor);
|
|
1944
|
+
kml += (labelsToAdd);
|
|
1945
|
+
}
|
|
1946
|
+
|
|
1947
|
+
kml += ("</Folder>");
|
|
1948
|
+
return kml.toString();
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
/**
|
|
1952
|
+
*
|
|
1953
|
+
* @param shapes
|
|
1954
|
+
* @param modifiers
|
|
1955
|
+
* @param ipc
|
|
1956
|
+
* @param geMap
|
|
1957
|
+
* @param normalize
|
|
1958
|
+
* @return
|
|
1959
|
+
* @deprecated Use GeoJSONize()
|
|
1960
|
+
*/
|
|
1961
|
+
private static JSONize(shapes: Array<ShapeInfo>, modifiers: Array<ShapeInfo>, ipc: IPointConversion, geMap: boolean, normalize: boolean): string {
|
|
1962
|
+
let polygons: string = "";
|
|
1963
|
+
let lines: string = "";
|
|
1964
|
+
let labels: string = "";
|
|
1965
|
+
let jstr: string = "";
|
|
1966
|
+
let tempModifier: ShapeInfo;
|
|
1967
|
+
|
|
1968
|
+
let len: int = shapes.length;
|
|
1969
|
+
for (let i: int = 0; i < len; i++) {
|
|
1970
|
+
if (jstr.length > 0) {
|
|
1971
|
+
jstr += ",";
|
|
1972
|
+
}
|
|
1973
|
+
let shapesToAdd: string = MultiPointHandler.ShapeToJSONString(shapes[i], ipc, geMap, normalize);
|
|
1974
|
+
if (shapesToAdd.length > 0) {
|
|
1975
|
+
if (shapesToAdd.startsWith("line", 2)) {
|
|
1976
|
+
if (lines.length > 0) {
|
|
1977
|
+
lines += ",";
|
|
1978
|
+
}
|
|
1979
|
+
|
|
1980
|
+
lines += shapesToAdd;
|
|
1981
|
+
} else {
|
|
1982
|
+
if (shapesToAdd.startsWith("polygon", 2)) {
|
|
1983
|
+
if (polygons.length > 0) {
|
|
1984
|
+
polygons += ",";
|
|
1985
|
+
}
|
|
1986
|
+
|
|
1987
|
+
polygons += shapesToAdd;
|
|
1988
|
+
}
|
|
1989
|
+
}
|
|
1990
|
+
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
|
|
1994
|
+
jstr += "\"polygons\": [" + polygons + "],"
|
|
1995
|
+
+ "\"lines\": [" + lines + "],";
|
|
1996
|
+
let len2: int = modifiers.length;
|
|
1997
|
+
labels = "";
|
|
1998
|
+
for (let j: int = 0; j < len2; j++) {
|
|
1999
|
+
tempModifier = modifiers[j];
|
|
2000
|
+
if (geMap) {
|
|
2001
|
+
MultiPointHandler.AdjustModifierPointToCenter(tempModifier);
|
|
2002
|
+
}
|
|
2003
|
+
let labelsToAdd: string = MultiPointHandler.LabelToJSONString(tempModifier, ipc, normalize);
|
|
2004
|
+
if (labelsToAdd.length > 0) {
|
|
2005
|
+
if (labels.length > 0) {
|
|
2006
|
+
labels += ",";
|
|
2007
|
+
}
|
|
2008
|
+
|
|
2009
|
+
labels += labelsToAdd;
|
|
2010
|
+
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
2013
|
+
jstr += "\"labels\": [" + labels + "]";
|
|
2014
|
+
return jstr;
|
|
2015
|
+
}
|
|
2016
|
+
|
|
2017
|
+
private static getIdealTextBackgroundColor(fgColor: Color): Color {
|
|
2018
|
+
//ErrorLogger.LogMessage("SymbolDraw","getIdealtextBGColor", "in function", Level.SEVERE);
|
|
2019
|
+
try {
|
|
2020
|
+
//an array of three elements containing the
|
|
2021
|
+
//hue, saturation, and brightness (in that order),
|
|
2022
|
+
//of the color with the indicated red, green, and blue components/
|
|
2023
|
+
let hsbvals: double[] = new Array<number>(3);
|
|
2024
|
+
|
|
2025
|
+
if (fgColor != null) {/*
|
|
2026
|
+
Color.RGBtoHSB(fgColor.getRed(), fgColor.getGreen(), fgColor.getBlue(), hsbvals);
|
|
2027
|
+
|
|
2028
|
+
if(hsbvals != null)
|
|
2029
|
+
{
|
|
2030
|
+
//ErrorLogger.LogMessage("SymbolDraw","getIdealtextBGColor", "length: " + hsbvals.length.toString());
|
|
2031
|
+
//ErrorLogger.LogMessage("SymbolDraw","getIdealtextBGColor", "H: " + String.valueOf(hsbvals[0]) + " S: " + String.valueOf(hsbvals[1]) + " B: " + String.valueOf(hsbvals[2]),Level.SEVERE);
|
|
2032
|
+
if(hsbvals[2] > 0.6)
|
|
2033
|
+
return Color.BLACK;
|
|
2034
|
+
else
|
|
2035
|
+
return Color.WHITE;
|
|
2036
|
+
}*/
|
|
2037
|
+
|
|
2038
|
+
let nThreshold: int = RendererSettings.getInstance().getTextBackgroundAutoColorThreshold();//160;
|
|
2039
|
+
let bgDelta: int = Math.trunc((fgColor.getRed() * 0.299) + (fgColor.getGreen() * 0.587) + (fgColor.getBlue() * 0.114));
|
|
2040
|
+
//ErrorLogger.LogMessage("bgDelta: " + String.valueOf(255-bgDelta));
|
|
2041
|
+
//if less than threshold, black, otherwise white.
|
|
2042
|
+
//return (255 - bgDelta < nThreshold) ? Color.BLACK : Color.WHITE;//new Color(0, 0, 0, fgColor.getAlpha())
|
|
2043
|
+
return (255 - bgDelta < nThreshold) ? new Color(0, 0, 0, fgColor.getAlpha()) : new Color(255, 255, 255, fgColor.getAlpha());
|
|
2044
|
+
}
|
|
2045
|
+
} catch (exc) {
|
|
2046
|
+
if (exc instanceof Error) {
|
|
2047
|
+
ErrorLogger.LogException("SymbolDraw", "getIdealtextBGColor", exc);
|
|
2048
|
+
} else {
|
|
2049
|
+
throw exc;
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
return Color.WHITE;
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
private static LabelToGeoJSONString(shapeInfo: ShapeInfo, ipc: IPointConversion, normalize: boolean, textColor: Color, textBackgroundColor: Color): string {
|
|
2056
|
+
|
|
2057
|
+
let JSONed: string = "";
|
|
2058
|
+
let properties: string = "";
|
|
2059
|
+
let geometry: string = "";
|
|
2060
|
+
|
|
2061
|
+
let outlineColor: Color = MultiPointHandler.getIdealTextBackgroundColor(textColor);
|
|
2062
|
+
if (textBackgroundColor != null) {
|
|
2063
|
+
outlineColor = textBackgroundColor;
|
|
2064
|
+
}
|
|
2065
|
+
|
|
2066
|
+
//AffineTransform at = shapeInfo.getAffineTransform();
|
|
2067
|
+
//Point2D coord = (Point2D)new Point2D(at.getTranslateX(), at.getTranslateY());
|
|
2068
|
+
//Point2D coord = (Point2D) new Point2D(shapeInfo.getGlyphPosition().getX(), shapeInfo.getGlyphPosition().getY());
|
|
2069
|
+
let coord: Point2D = new Point2D(shapeInfo.getModifierPosition().getX(), shapeInfo.getModifierPosition().getY()) as Point2D;
|
|
2070
|
+
let geoCoord: Point2D = ipc.PixelsToGeo(coord);
|
|
2071
|
+
//M. Deutch 9-27-11
|
|
2072
|
+
if (normalize) {
|
|
2073
|
+
geoCoord = MultiPointHandler.NormalizeCoordToGECoord(geoCoord);
|
|
2074
|
+
}
|
|
2075
|
+
let latitude: double = Math.round(geoCoord.getY() * 100000000.0) / 100000000.0;
|
|
2076
|
+
let longitude: double = Math.round(geoCoord.getX() * 100000000.0) / 100000000.0;
|
|
2077
|
+
let angle: double = shapeInfo.getModifierAngle();
|
|
2078
|
+
coord.setLocation(longitude, latitude);
|
|
2079
|
+
|
|
2080
|
+
//diagnostic M. Deutch 10-18-11
|
|
2081
|
+
shapeInfo.setGlyphPosition(coord);
|
|
2082
|
+
|
|
2083
|
+
let text: string = shapeInfo.getModifierString();
|
|
2084
|
+
|
|
2085
|
+
let justify: int = shapeInfo.getTextJustify();
|
|
2086
|
+
let strJustify: string = "left";
|
|
2087
|
+
if (justify === 0) {
|
|
2088
|
+
strJustify = "left";
|
|
2089
|
+
} else {
|
|
2090
|
+
if (justify === 1) {
|
|
2091
|
+
strJustify = "center";
|
|
2092
|
+
} else {
|
|
2093
|
+
if (justify === 2) {
|
|
2094
|
+
strJustify = "right";
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
|
|
2098
|
+
}
|
|
2099
|
+
|
|
2100
|
+
|
|
2101
|
+
let RS: RendererSettings = RendererSettings.getInstance();
|
|
2102
|
+
|
|
2103
|
+
if (text != null && text !== "") {
|
|
2104
|
+
|
|
2105
|
+
JSONed += ("{\"type\":\"Feature\",\"properties\":{\"label\":\"");
|
|
2106
|
+
JSONed += (text);
|
|
2107
|
+
JSONed += ("\",\"pointRadius\":0,\"fontColor\":\"");
|
|
2108
|
+
JSONed += (RendererUtilities.colorToHexString(textColor, false));
|
|
2109
|
+
JSONed += ("\",\"fontSize\":\"");
|
|
2110
|
+
JSONed += (RS.getMPLabelFont().getSize().toString() + "pt\"");
|
|
2111
|
+
JSONed += (",\"fontFamily\":\"");
|
|
2112
|
+
JSONed += (RS.getMPLabelFont().getName());
|
|
2113
|
+
JSONed += (", sans-serif");
|
|
2114
|
+
|
|
2115
|
+
if (RS.getMPLabelFont().getType() === Font.BOLD) {
|
|
2116
|
+
JSONed += ("\",\"fontWeight\":\"bold\"");
|
|
2117
|
+
} else {
|
|
2118
|
+
JSONed += ("\",\"fontWeight\":\"normal\"");
|
|
2119
|
+
}
|
|
2120
|
+
|
|
2121
|
+
//JSONed += (",\"labelAlign\":\"lm\"");
|
|
2122
|
+
JSONed += (",\"labelAlign\":\"");
|
|
2123
|
+
JSONed += (strJustify);
|
|
2124
|
+
JSONed += ("\",\"labelBaseline\":\"alphabetic");
|
|
2125
|
+
JSONed += ("\",\"labelXOffset\":0");
|
|
2126
|
+
JSONed += (",\"labelYOffset\":0");
|
|
2127
|
+
JSONed += (",\"labelOutlineColor\":\"");
|
|
2128
|
+
JSONed += (RendererUtilities.colorToHexString(outlineColor, false));
|
|
2129
|
+
JSONed += ("\",\"labelOutlineWidth\":");
|
|
2130
|
+
JSONed += ("4");
|
|
2131
|
+
JSONed += (",\"rotation\":");
|
|
2132
|
+
JSONed += (angle);
|
|
2133
|
+
JSONed += (",\"angle\":");
|
|
2134
|
+
JSONed += (angle);
|
|
2135
|
+
JSONed += ("},");
|
|
2136
|
+
|
|
2137
|
+
JSONed += ("\"geometry\":{\"type\":\"Point\",\"coordinates\":[");
|
|
2138
|
+
JSONed += (longitude);
|
|
2139
|
+
JSONed += (",");
|
|
2140
|
+
JSONed += (latitude);
|
|
2141
|
+
JSONed += ("]");
|
|
2142
|
+
JSONed += ("}}");
|
|
2143
|
+
|
|
2144
|
+
} else {
|
|
2145
|
+
return "";
|
|
2146
|
+
}
|
|
2147
|
+
|
|
2148
|
+
return JSONed.toString();
|
|
2149
|
+
}
|
|
2150
|
+
|
|
2151
|
+
private static ShapeToGeoJSONString(shapeInfo: ShapeInfo, ipc: IPointConversion, normalize: boolean): string {
|
|
2152
|
+
let JSONed: string = "";
|
|
2153
|
+
let properties: string = "";
|
|
2154
|
+
let geometry: string = "";
|
|
2155
|
+
let geometryType: string;
|
|
2156
|
+
let sda: string;
|
|
2157
|
+
/*
|
|
2158
|
+
NOTE: Google Earth / KML colors are backwards.
|
|
2159
|
+
They are ordered Alpha,Blue,Green,Red, not Red,Green,Blue,Aplha like the rest of the world
|
|
2160
|
+
* */
|
|
2161
|
+
let lineColor: Color = shapeInfo.getLineColor();
|
|
2162
|
+
let fillColor: Color = shapeInfo.getFillColor();
|
|
2163
|
+
|
|
2164
|
+
if (shapeInfo.getShapeType() === ShapeInfo.SHAPE_TYPE_FILL || fillColor != null || shapeInfo.getPatternFillImage() != null) {
|
|
2165
|
+
geometryType = "\"Polygon\"";
|
|
2166
|
+
} else //if(shapeInfo.getShapeType() == ShapeInfo.SHAPE_TYPE_POLYLINE)
|
|
2167
|
+
{
|
|
2168
|
+
geometryType = "\"MultiLineString\"";
|
|
2169
|
+
}
|
|
2170
|
+
|
|
2171
|
+
let stroke: BasicStroke;
|
|
2172
|
+
stroke = shapeInfo.getStroke();
|
|
2173
|
+
let lineWidth: int = 4;
|
|
2174
|
+
|
|
2175
|
+
if (stroke != null) {
|
|
2176
|
+
lineWidth = Math.trunc(stroke.getLineWidth());
|
|
2177
|
+
//lineWidth++;
|
|
2178
|
+
//console.log("lineWidth: " + lineWidth.toString());
|
|
2179
|
+
}
|
|
2180
|
+
|
|
2181
|
+
//generate JSON properties for feature
|
|
2182
|
+
properties += ("\"properties\":{");
|
|
2183
|
+
properties += ("\"label\":\"\",");
|
|
2184
|
+
if (lineColor != null) {
|
|
2185
|
+
properties += ("\"strokeColor\":\"" + RendererUtilities.colorToHexString(lineColor, false) + "\",");
|
|
2186
|
+
properties += ("\"lineOpacity\":" + (lineColor.getAlpha() / 255).toString() + ",");
|
|
2187
|
+
}
|
|
2188
|
+
if (fillColor != null) {
|
|
2189
|
+
properties += ("\"fillColor\":\"" + RendererUtilities.colorToHexString(fillColor, false) + "\",");
|
|
2190
|
+
properties += ("\"fillOpacity\":" + (fillColor.getAlpha() / 255).toString() + ",");
|
|
2191
|
+
}
|
|
2192
|
+
if (shapeInfo.getPatternFillImage() != null) {
|
|
2193
|
+
properties += ("\"fillPattern\":\"" + shapeInfo.getPatternFillImage() + "\",");
|
|
2194
|
+
}
|
|
2195
|
+
if (stroke.getDashArray() != null) {
|
|
2196
|
+
sda = "\"strokeDasharray\":[" + stroke.getDashArray().toString() + "],";
|
|
2197
|
+
properties += (sda);
|
|
2198
|
+
}
|
|
2199
|
+
|
|
2200
|
+
|
|
2201
|
+
let lineCap: int = stroke.getEndCap();
|
|
2202
|
+
properties += ("\"lineCap\":" + lineCap + ",");
|
|
2203
|
+
|
|
2204
|
+
let strokeWidth: string = lineWidth.toString();
|
|
2205
|
+
properties += ("\"strokeWidth\":" + strokeWidth + ",");
|
|
2206
|
+
properties += ("\"strokeWeight\":" + strokeWidth + "");
|
|
2207
|
+
properties += ("},");
|
|
2208
|
+
|
|
2209
|
+
|
|
2210
|
+
properties += ("\"style\":{");
|
|
2211
|
+
if (lineColor != null) {
|
|
2212
|
+
properties += ("\"stroke\":\"" + RendererUtilities.colorToHexString(lineColor, false) + "\",");
|
|
2213
|
+
properties += ("\"line-opacity\":" + (lineColor.getAlpha() / 255).toString() + ",");
|
|
2214
|
+
}
|
|
2215
|
+
if (fillColor != null) {
|
|
2216
|
+
properties += ("\"fill\":\"" + RendererUtilities.colorToHexString(fillColor, false) + "\",");
|
|
2217
|
+
properties += ("\"fill-opacity\":" + (fillColor.getAlpha() / 255).toString() + ",");
|
|
2218
|
+
}
|
|
2219
|
+
if (stroke.getDashArray() != null) {
|
|
2220
|
+
let da: number[] = stroke.getDashArray();
|
|
2221
|
+
sda = da[0].toString();
|
|
2222
|
+
if (da.length > 1) {
|
|
2223
|
+
for (let i: int = 1; i < da.length; i++) {
|
|
2224
|
+
sda = sda + " " + da[i].toString();
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
sda = "\"stroke-dasharray\":\"" + sda + "\",";
|
|
2228
|
+
properties += (sda);
|
|
2229
|
+
sda = null;
|
|
2230
|
+
}
|
|
2231
|
+
|
|
2232
|
+
if (lineCap === BasicStroke.CAP_SQUARE) {
|
|
2233
|
+
|
|
2234
|
+
properties += ("\"stroke-linecap\":\"square\",");
|
|
2235
|
+
}
|
|
2236
|
+
|
|
2237
|
+
else {
|
|
2238
|
+
if (lineCap === BasicStroke.CAP_ROUND) {
|
|
2239
|
+
|
|
2240
|
+
properties += ("\"stroke-linecap\":\"round\",");
|
|
2241
|
+
}
|
|
2242
|
+
|
|
2243
|
+
else {
|
|
2244
|
+
if (lineCap === BasicStroke.CAP_BUTT) {
|
|
2245
|
+
|
|
2246
|
+
properties += ("\"stroke-linecap\":\"butt\",");
|
|
2247
|
+
}
|
|
2248
|
+
|
|
2249
|
+
}
|
|
2250
|
+
|
|
2251
|
+
}
|
|
2252
|
+
|
|
2253
|
+
|
|
2254
|
+
strokeWidth = lineWidth.toString();
|
|
2255
|
+
properties += ("\"stroke-width\":" + strokeWidth);
|
|
2256
|
+
properties += ("}");
|
|
2257
|
+
|
|
2258
|
+
|
|
2259
|
+
//generate JSON geometry for feature
|
|
2260
|
+
geometry += ("\"geometry\":{\"type\":");
|
|
2261
|
+
geometry += (geometryType);
|
|
2262
|
+
geometry += (",\"coordinates\":[");
|
|
2263
|
+
|
|
2264
|
+
let shapesArray: Point2D[][] = shapeInfo.getPolylines();
|
|
2265
|
+
|
|
2266
|
+
for (let i: int = 0; i < shapesArray.length; i++) {
|
|
2267
|
+
let pointList: Point2D[] = shapesArray[i];
|
|
2268
|
+
|
|
2269
|
+
normalize = MultiPointHandler.normalizePoints(pointList, ipc);
|
|
2270
|
+
|
|
2271
|
+
geometry += ("[");
|
|
2272
|
+
|
|
2273
|
+
//console.log("Pixel Coords:");
|
|
2274
|
+
for (let j: int = 0; j < pointList.length; j++) {
|
|
2275
|
+
let coord: Point2D = pointList[j] as Point2D;
|
|
2276
|
+
let geoCoord: Point2D = ipc.PixelsToGeo(coord);
|
|
2277
|
+
//M. Deutch 9-27-11
|
|
2278
|
+
if (normalize) {
|
|
2279
|
+
geoCoord = MultiPointHandler.NormalizeCoordToGECoord(geoCoord);
|
|
2280
|
+
}
|
|
2281
|
+
let latitude: double = Math.round(geoCoord.getY() * 100000000.0) / 100000000.0;
|
|
2282
|
+
let longitude: double = Math.round(geoCoord.getX() * 100000000.0) / 100000000.0;
|
|
2283
|
+
|
|
2284
|
+
//fix for fill crossing DTL
|
|
2285
|
+
if (normalize && fillColor != null) {
|
|
2286
|
+
if (longitude > 0) {
|
|
2287
|
+
longitude -= 360;
|
|
2288
|
+
}
|
|
2289
|
+
}
|
|
2290
|
+
|
|
2291
|
+
//diagnostic M. Deutch 10-18-11
|
|
2292
|
+
//set the point as geo so that the
|
|
2293
|
+
//coord.setLocation(longitude, latitude);
|
|
2294
|
+
coord = new Point2D(longitude, latitude);
|
|
2295
|
+
pointList[j] = coord;
|
|
2296
|
+
//end section
|
|
2297
|
+
|
|
2298
|
+
geometry += ("[");
|
|
2299
|
+
geometry += (longitude);
|
|
2300
|
+
geometry += (",");
|
|
2301
|
+
geometry += (latitude);
|
|
2302
|
+
geometry += ("]");
|
|
2303
|
+
|
|
2304
|
+
if (j < (pointList.length - 1)) {
|
|
2305
|
+
geometry += (",");
|
|
2306
|
+
}
|
|
2307
|
+
}
|
|
2308
|
+
|
|
2309
|
+
geometry += ("]");
|
|
2310
|
+
|
|
2311
|
+
if (i < (shapesArray.length - 1)) {
|
|
2312
|
+
geometry += (",");
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2315
|
+
geometry += ("]}");
|
|
2316
|
+
|
|
2317
|
+
JSONed += ("{\"type\":\"Feature\",");
|
|
2318
|
+
JSONed += (properties.toString());
|
|
2319
|
+
JSONed += (",");
|
|
2320
|
+
JSONed += (geometry.toString());
|
|
2321
|
+
JSONed += ("}");
|
|
2322
|
+
|
|
2323
|
+
return JSONed.toString();
|
|
2324
|
+
}
|
|
2325
|
+
|
|
2326
|
+
private static ImageToGeoJSONString(shapeInfo: ShapeInfo, ipc: IPointConversion, normalize: boolean): string {
|
|
2327
|
+
|
|
2328
|
+
let JSONed: string = "";
|
|
2329
|
+
let properties: string = "";
|
|
2330
|
+
let geometry: string = "";
|
|
2331
|
+
|
|
2332
|
+
//AffineTransform at = shapeInfo.getAffineTransform();
|
|
2333
|
+
//Point2D coord = (Point2D)new Point2D(at.getTranslateX(), at.getTranslateY());
|
|
2334
|
+
//Point2D coord = (Point2D) new Point2D(shapeInfo.getGlyphPosition().getX(), shapeInfo.getGlyphPosition().getY());
|
|
2335
|
+
let coord: Point2D = new Point2D(shapeInfo.getModifierPosition().getX(), shapeInfo.getModifierPosition().getY()) as Point2D;
|
|
2336
|
+
let geoCoord: Point2D = ipc.PixelsToGeo(coord);
|
|
2337
|
+
//M. Deutch 9-27-11
|
|
2338
|
+
if (normalize) {
|
|
2339
|
+
geoCoord = MultiPointHandler.NormalizeCoordToGECoord(geoCoord);
|
|
2340
|
+
}
|
|
2341
|
+
let latitude: double = Math.round(geoCoord.getY() * 100000000.0) / 100000000.0;
|
|
2342
|
+
let longitude: double = Math.round(geoCoord.getX() * 100000000.0) / 100000000.0;
|
|
2343
|
+
let angle: double = shapeInfo.getModifierAngle();
|
|
2344
|
+
coord.setLocation(longitude, latitude);
|
|
2345
|
+
|
|
2346
|
+
//diagnostic M. Deutch 10-18-11
|
|
2347
|
+
shapeInfo.setGlyphPosition(coord);
|
|
2348
|
+
|
|
2349
|
+
let image: string = shapeInfo.getModifierImage();
|
|
2350
|
+
|
|
2351
|
+
let RS: RendererSettings = RendererSettings.getInstance();
|
|
2352
|
+
|
|
2353
|
+
if (image != null) {
|
|
2354
|
+
|
|
2355
|
+
JSONed += ("{\"type\":\"Feature\",\"properties\":{\"image\":\"");
|
|
2356
|
+
JSONed += (image);
|
|
2357
|
+
JSONed += ("\",\"rotation\":");
|
|
2358
|
+
JSONed += (angle);
|
|
2359
|
+
JSONed += (",\"angle\":");
|
|
2360
|
+
JSONed += (angle);
|
|
2361
|
+
JSONed += ("},");
|
|
2362
|
+
JSONed += ("\"geometry\":{\"type\":\"Point\",\"coordinates\":[");
|
|
2363
|
+
JSONed += (longitude);
|
|
2364
|
+
JSONed += (",");
|
|
2365
|
+
JSONed += (latitude);
|
|
2366
|
+
JSONed += ("]");
|
|
2367
|
+
JSONed += ("}}");
|
|
2368
|
+
|
|
2369
|
+
} else {
|
|
2370
|
+
return "";
|
|
2371
|
+
}
|
|
2372
|
+
|
|
2373
|
+
return JSONed.toString();
|
|
2374
|
+
}
|
|
2375
|
+
|
|
2376
|
+
private static GeoJSONize(shapes: Array<ShapeInfo>, modifiers: Array<ShapeInfo>, ipc: IPointConversion, normalize: boolean, textColor: Color, textBackgroundColor: Color): string {
|
|
2377
|
+
|
|
2378
|
+
let jstr: string = "";
|
|
2379
|
+
let tempModifier: ShapeInfo;
|
|
2380
|
+
let fc: string = "";//JSON feature collection
|
|
2381
|
+
|
|
2382
|
+
fc += ("[");
|
|
2383
|
+
|
|
2384
|
+
let len: int = shapes.length;
|
|
2385
|
+
for (let i: int = 0; i < len; i++)
|
|
2386
|
+
{
|
|
2387
|
+
|
|
2388
|
+
let shapesToAdd: string = null;
|
|
2389
|
+
let tempShape:ShapeInfo = shapes[i];
|
|
2390
|
+
if(tempShape != null && tempShape !== undefined)
|
|
2391
|
+
shapesToAdd = MultiPointHandler.ShapeToGeoJSONString(tempShape, ipc, normalize);
|
|
2392
|
+
if (shapesToAdd != null && shapesToAdd.length > 0) {
|
|
2393
|
+
fc += (shapesToAdd);
|
|
2394
|
+
}
|
|
2395
|
+
if (shapesToAdd != null && i < len - 1) {
|
|
2396
|
+
fc += (",");
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
|
|
2400
|
+
let len2: int = modifiers.length;
|
|
2401
|
+
|
|
2402
|
+
for (let j: int = 0; j < len2; j++) {
|
|
2403
|
+
tempModifier = modifiers[j];
|
|
2404
|
+
|
|
2405
|
+
let modifiersToAdd: string;
|
|
2406
|
+
if (modifiers[j].getModifierImage() != null) {
|
|
2407
|
+
modifiersToAdd = MultiPointHandler.ImageToGeoJSONString(tempModifier, ipc, normalize);
|
|
2408
|
+
} else {
|
|
2409
|
+
modifiersToAdd = MultiPointHandler.LabelToGeoJSONString(tempModifier, ipc, normalize, textColor, textBackgroundColor);
|
|
2410
|
+
}
|
|
2411
|
+
if (modifiersToAdd.length > 0) {
|
|
2412
|
+
fc += (",");
|
|
2413
|
+
fc += (modifiersToAdd);
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
fc += ("]");
|
|
2417
|
+
let GeoJSON: string = fc.toString();
|
|
2418
|
+
return GeoJSON;
|
|
2419
|
+
}
|
|
2420
|
+
|
|
2421
|
+
/**
|
|
2422
|
+
*
|
|
2423
|
+
* @param shapes
|
|
2424
|
+
* @param modifiers
|
|
2425
|
+
* @param ipc
|
|
2426
|
+
* @param normalize
|
|
2427
|
+
* @deprecated
|
|
2428
|
+
*/
|
|
2429
|
+
private static MakeWWReady(
|
|
2430
|
+
shapes: Array<ShapeInfo>,
|
|
2431
|
+
modifiers: Array<ShapeInfo>,
|
|
2432
|
+
ipc: IPointConversion,
|
|
2433
|
+
normalize: boolean): void {
|
|
2434
|
+
let temp: ShapeInfo;
|
|
2435
|
+
let len: int = shapes.length;
|
|
2436
|
+
for (let i: int = 0; i < len; i++) {
|
|
2437
|
+
|
|
2438
|
+
temp = MultiPointHandler.ShapeToWWReady(shapes[i], ipc, normalize);
|
|
2439
|
+
shapes[i] = temp;
|
|
2440
|
+
|
|
2441
|
+
}
|
|
2442
|
+
|
|
2443
|
+
let len2: int = modifiers.length;
|
|
2444
|
+
let tempModifier: ShapeInfo;
|
|
2445
|
+
for (let j: int = 0; j < len2; j++) {
|
|
2446
|
+
|
|
2447
|
+
tempModifier = modifiers[j];
|
|
2448
|
+
|
|
2449
|
+
//Do we need this for World Wind?
|
|
2450
|
+
tempModifier = MultiPointHandler.LabelToWWReady(tempModifier, ipc, normalize);
|
|
2451
|
+
modifiers[j] = tempModifier;
|
|
2452
|
+
|
|
2453
|
+
}
|
|
2454
|
+
|
|
2455
|
+
}
|
|
2456
|
+
|
|
2457
|
+
private static normalizePoints(shape: Array<Point2D>, ipc: IPointConversion): boolean {
|
|
2458
|
+
let geoCoords: Point2D[] = new Array();
|
|
2459
|
+
let n: int = shape.length;
|
|
2460
|
+
//for (int j = 0; j < shape.length; j++)
|
|
2461
|
+
for (let j: int = 0; j < n; j++) {
|
|
2462
|
+
let coord: Point2D = shape[j];
|
|
2463
|
+
let geoCoord: Point2D = ipc.PixelsToGeo(coord);
|
|
2464
|
+
geoCoord = MultiPointHandler.NormalizeCoordToGECoord(geoCoord);
|
|
2465
|
+
let latitude: double = geoCoord.getY();
|
|
2466
|
+
let longitude: double = geoCoord.getX();
|
|
2467
|
+
let pt2d: Point2D = new Point2D(longitude, latitude);
|
|
2468
|
+
geoCoords.push(pt2d);
|
|
2469
|
+
}
|
|
2470
|
+
let normalize: boolean = MultiPointHandler.crossesIDL(geoCoords);
|
|
2471
|
+
return normalize;
|
|
2472
|
+
}
|
|
2473
|
+
|
|
2474
|
+
private static IsOnePointSymbolCode(symbolCode: string): boolean {
|
|
2475
|
+
let basicCode: string = SymbolUtilities.getBasicSymbolID(symbolCode);
|
|
2476
|
+
//TODO: Revisit for basic shapes
|
|
2477
|
+
//some airspaces affected
|
|
2478
|
+
if (symbolCode === "CAKE-----------") {
|
|
2479
|
+
return true;
|
|
2480
|
+
} else {
|
|
2481
|
+
if (symbolCode === "CYLINDER-------") {
|
|
2482
|
+
return true;
|
|
2483
|
+
} else {
|
|
2484
|
+
if (symbolCode === "RADARC---------") {
|
|
2485
|
+
return true;
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
|
|
2489
|
+
}
|
|
2490
|
+
|
|
2491
|
+
|
|
2492
|
+
return false;
|
|
2493
|
+
}
|
|
2494
|
+
|
|
2495
|
+
private static ShapeToKMLString(name: string,
|
|
2496
|
+
description: string,
|
|
2497
|
+
symbolCode: string,
|
|
2498
|
+
shapeInfo: ShapeInfo,
|
|
2499
|
+
ipc: IPointConversion,
|
|
2500
|
+
normalize: boolean): string {
|
|
2501
|
+
|
|
2502
|
+
let kml: string = "";
|
|
2503
|
+
|
|
2504
|
+
let lineColor: Color;
|
|
2505
|
+
let fillColor: Color;
|
|
2506
|
+
let googleLineColor: string;
|
|
2507
|
+
let googleFillColor: string;
|
|
2508
|
+
|
|
2509
|
+
//String lineStyleId = "lineColor";
|
|
2510
|
+
|
|
2511
|
+
let stroke: BasicStroke;
|
|
2512
|
+
let lineWidth: int = 4;
|
|
2513
|
+
|
|
2514
|
+
symbolCode = JavaRendererUtilities.normalizeSymbolCode(symbolCode);
|
|
2515
|
+
|
|
2516
|
+
let cdataStart: string = "<![CDATA[";
|
|
2517
|
+
let cdataEnd: string = "]]>";
|
|
2518
|
+
|
|
2519
|
+
kml += ("<Placemark>");//("<Placemark id=\"" + id + "_mg" + "\">");
|
|
2520
|
+
kml += ("<description>" + cdataStart + "<b>" + name + "</b><br/>" + "\n" + description + cdataEnd + "</description>");
|
|
2521
|
+
//kml += ("<Style id=\"" + lineStyleId + "\">");
|
|
2522
|
+
kml += ("<Style>");
|
|
2523
|
+
|
|
2524
|
+
lineColor = shapeInfo.getLineColor();
|
|
2525
|
+
if (lineColor != null) {
|
|
2526
|
+
googleLineColor = RendererUtilities.colorToHexString(shapeInfo.getLineColor(), false).substring(1);
|
|
2527
|
+
|
|
2528
|
+
stroke = shapeInfo.getStroke();
|
|
2529
|
+
|
|
2530
|
+
if (stroke != null) {
|
|
2531
|
+
lineWidth = stroke.getLineWidth() as int;
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2534
|
+
googleLineColor = JavaRendererUtilities.ARGBtoABGR(googleLineColor);
|
|
2535
|
+
|
|
2536
|
+
kml += ("<LineStyle>");
|
|
2537
|
+
kml += ("<color>" + googleLineColor + "</color>");
|
|
2538
|
+
kml += ("<colorMode>normal</colorMode>");
|
|
2539
|
+
kml += ("<width>" + lineWidth.toString() + "</width>");
|
|
2540
|
+
kml += ("</LineStyle>");
|
|
2541
|
+
}
|
|
2542
|
+
|
|
2543
|
+
fillColor = shapeInfo.getFillColor();
|
|
2544
|
+
let fillPattern: string = shapeInfo.getPatternFillImage();
|
|
2545
|
+
if (fillColor != null || fillPattern != null) {
|
|
2546
|
+
kml += ("<PolyStyle>");
|
|
2547
|
+
|
|
2548
|
+
if (fillColor != null) {
|
|
2549
|
+
googleFillColor = RendererUtilities.colorToHexString(shapeInfo.getFillColor(), false).substring(1);
|
|
2550
|
+
googleFillColor = JavaRendererUtilities.ARGBtoABGR(googleFillColor);
|
|
2551
|
+
kml += ("<color>" + googleFillColor + "</color>");
|
|
2552
|
+
kml += ("<colorMode>normal</colorMode>");
|
|
2553
|
+
}
|
|
2554
|
+
if (fillPattern != null) {
|
|
2555
|
+
kml += ("<shader>" + fillPattern + "</shader>");
|
|
2556
|
+
}
|
|
2557
|
+
|
|
2558
|
+
kml += ("<fill>1</fill>");
|
|
2559
|
+
if (lineColor != null) {
|
|
2560
|
+
kml += ("<outline>1</outline>");
|
|
2561
|
+
} else {
|
|
2562
|
+
kml += ("<outline>0</outline>");
|
|
2563
|
+
}
|
|
2564
|
+
kml += ("</PolyStyle>");
|
|
2565
|
+
}
|
|
2566
|
+
|
|
2567
|
+
kml += ("</Style>");
|
|
2568
|
+
|
|
2569
|
+
let shapesArray: Point2D[][] = shapeInfo.getPolylines();
|
|
2570
|
+
let len: int = shapesArray.length;
|
|
2571
|
+
kml += ("<MultiGeometry>");
|
|
2572
|
+
|
|
2573
|
+
for (let i: int = 0; i < len; i++) {
|
|
2574
|
+
let shape: Point2D[] = shapesArray[i];
|
|
2575
|
+
normalize = MultiPointHandler.normalizePoints(shape, ipc);
|
|
2576
|
+
if (lineColor != null && fillColor == null) {
|
|
2577
|
+
kml += ("<LineString>");
|
|
2578
|
+
kml += ("<tessellate>1</tessellate>");
|
|
2579
|
+
kml += ("<altitudeMode>clampToGround</altitudeMode>");
|
|
2580
|
+
kml += ("<coordinates>");
|
|
2581
|
+
let n: int = shape.length;
|
|
2582
|
+
//for (int j = 0; j < shape.length; j++)
|
|
2583
|
+
for (let j: int = 0; j < n; j++) {
|
|
2584
|
+
let coord: Point2D = shape[j] as Point2D;
|
|
2585
|
+
let geoCoord: Point2D = ipc.PixelsToGeo(coord);
|
|
2586
|
+
if (normalize) {
|
|
2587
|
+
geoCoord = MultiPointHandler.NormalizeCoordToGECoord(geoCoord);
|
|
2588
|
+
}
|
|
2589
|
+
|
|
2590
|
+
let latitude: double = Math.round(geoCoord.getY() * 100000000.0) / 100000000.0;
|
|
2591
|
+
let longitude: double = Math.round(geoCoord.getX() * 100000000.0) / 100000000.0;
|
|
2592
|
+
|
|
2593
|
+
kml += (longitude);
|
|
2594
|
+
kml += (",");
|
|
2595
|
+
kml += (latitude);
|
|
2596
|
+
if (j < shape.length - 1) {
|
|
2597
|
+
|
|
2598
|
+
kml += (" ");
|
|
2599
|
+
}
|
|
2600
|
+
|
|
2601
|
+
}
|
|
2602
|
+
|
|
2603
|
+
kml += ("</coordinates>");
|
|
2604
|
+
kml += ("</LineString>");
|
|
2605
|
+
}
|
|
2606
|
+
|
|
2607
|
+
if (fillColor != null) {
|
|
2608
|
+
|
|
2609
|
+
if (i === 0) {
|
|
2610
|
+
kml += ("<Polygon>");
|
|
2611
|
+
}
|
|
2612
|
+
//kml += ("<outerBoundaryIs>");
|
|
2613
|
+
if (i === 1 && len > 1) {
|
|
2614
|
+
kml += ("<innerBoundaryIs>");
|
|
2615
|
+
} else {
|
|
2616
|
+
kml += ("<outerBoundaryIs>");
|
|
2617
|
+
}
|
|
2618
|
+
kml += ("<LinearRing>");
|
|
2619
|
+
kml += ("<altitudeMode>clampToGround</altitudeMode>");
|
|
2620
|
+
kml += ("<tessellate>1</tessellate>");
|
|
2621
|
+
kml += ("<coordinates>");
|
|
2622
|
+
|
|
2623
|
+
//this section is a workaround for a google earth bug. Issue 417 was closed
|
|
2624
|
+
//for linestrings but they did not fix the smae issue for fills. If Google fixes the issue
|
|
2625
|
+
//for fills then this section will need to be commented or it will induce an error.
|
|
2626
|
+
let lastLongitude: double = Number.MIN_VALUE;
|
|
2627
|
+
if (normalize === false && MultiPointHandler.IsOnePointSymbolCode(symbolCode)) {
|
|
2628
|
+
let n: int = shape.length;
|
|
2629
|
+
//for (int j = 0; j < shape.length; j++)
|
|
2630
|
+
for (let j: int = 0; j < n; j++) {
|
|
2631
|
+
let coord: Point2D = shape[j] as Point2D;
|
|
2632
|
+
let geoCoord: Point2D = ipc.PixelsToGeo(coord);
|
|
2633
|
+
let longitude: double = geoCoord.getX();
|
|
2634
|
+
if (lastLongitude !== Number.MIN_VALUE) {
|
|
2635
|
+
if (Math.abs(longitude - lastLongitude) > 180) {
|
|
2636
|
+
normalize = true;
|
|
2637
|
+
break;
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2640
|
+
lastLongitude = longitude;
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
let n: int = shape.length;
|
|
2644
|
+
//for (int j = 0; j < shape.length; j++)
|
|
2645
|
+
for (let j: int = 0; j < n; j++) {
|
|
2646
|
+
let coord: Point2D = shape[j] as Point2D;
|
|
2647
|
+
let geoCoord: Point2D = ipc.PixelsToGeo(coord);
|
|
2648
|
+
|
|
2649
|
+
let latitude: double = Math.round(geoCoord.getY() * 100000000.0) / 100000000.0;
|
|
2650
|
+
let longitude: double = Math.round(geoCoord.getX() * 100000000.0) / 100000000.0;
|
|
2651
|
+
|
|
2652
|
+
//fix for fill crossing DTL
|
|
2653
|
+
if (normalize) {
|
|
2654
|
+
if (longitude > 0) {
|
|
2655
|
+
longitude -= 360;
|
|
2656
|
+
}
|
|
2657
|
+
}
|
|
2658
|
+
|
|
2659
|
+
kml += (longitude);
|
|
2660
|
+
kml += (",");
|
|
2661
|
+
kml += (latitude);
|
|
2662
|
+
if (j < shape.length - 1) {
|
|
2663
|
+
|
|
2664
|
+
kml += (" ");
|
|
2665
|
+
}
|
|
2666
|
+
|
|
2667
|
+
}
|
|
2668
|
+
|
|
2669
|
+
kml += ("</coordinates>");
|
|
2670
|
+
kml += ("</LinearRing>");
|
|
2671
|
+
if (i === 1 && len > 1) {
|
|
2672
|
+
kml += ("</innerBoundaryIs>");
|
|
2673
|
+
} else {
|
|
2674
|
+
kml += ("</outerBoundaryIs>");
|
|
2675
|
+
}
|
|
2676
|
+
if (i === len - 1) {
|
|
2677
|
+
kml += ("</Polygon>");
|
|
2678
|
+
}
|
|
2679
|
+
}
|
|
2680
|
+
}
|
|
2681
|
+
|
|
2682
|
+
kml += ("</MultiGeometry>");
|
|
2683
|
+
kml += ("</Placemark>");
|
|
2684
|
+
|
|
2685
|
+
return kml.toString();
|
|
2686
|
+
}
|
|
2687
|
+
|
|
2688
|
+
/**
|
|
2689
|
+
*
|
|
2690
|
+
* @param shapeInfo
|
|
2691
|
+
* @param ipc
|
|
2692
|
+
* @param normalize
|
|
2693
|
+
* @return
|
|
2694
|
+
* @deprecated
|
|
2695
|
+
*/
|
|
2696
|
+
private static ShapeToWWReady(
|
|
2697
|
+
shapeInfo: ShapeInfo,
|
|
2698
|
+
ipc: IPointConversion,
|
|
2699
|
+
normalize: boolean): ShapeInfo {
|
|
2700
|
+
|
|
2701
|
+
let shapesArray: Point2D[][] = shapeInfo.getPolylines();
|
|
2702
|
+
let len: int = shapesArray.length;
|
|
2703
|
+
|
|
2704
|
+
for (let i: int = 0; i < len; i++) {
|
|
2705
|
+
let shape: Point2D[] = shapesArray[i];
|
|
2706
|
+
|
|
2707
|
+
if (shapeInfo.getLineColor() != null) {
|
|
2708
|
+
let n: int = shape.length;
|
|
2709
|
+
//for (int j = 0; j < shape.length; j++)
|
|
2710
|
+
for (let j: int = 0; j < n; j++) {
|
|
2711
|
+
let coord: Point2D = shape[j] as Point2D;
|
|
2712
|
+
let geoCoord: Point2D = ipc.PixelsToGeo(coord);
|
|
2713
|
+
//M. Deutch 9-26-11
|
|
2714
|
+
if (normalize) {
|
|
2715
|
+
geoCoord = MultiPointHandler.NormalizeCoordToGECoord(geoCoord);
|
|
2716
|
+
}
|
|
2717
|
+
|
|
2718
|
+
shape[j] = geoCoord;
|
|
2719
|
+
|
|
2720
|
+
}
|
|
2721
|
+
|
|
2722
|
+
}
|
|
2723
|
+
|
|
2724
|
+
if (shapeInfo.getFillColor() != null) {
|
|
2725
|
+
let n: int = shape.length;
|
|
2726
|
+
//for (int j = 0; j < shape.length; j++)
|
|
2727
|
+
for (let j: int = 0; j < n; j++) {
|
|
2728
|
+
let coord: Point2D = shape[j] as Point2D;
|
|
2729
|
+
let geoCoord: Point2D = ipc.PixelsToGeo(coord);
|
|
2730
|
+
//M. Deutch 9-26-11
|
|
2731
|
+
//commenting these two lines seems to help with fill not go around the pole
|
|
2732
|
+
//if(normalize)
|
|
2733
|
+
//geoCoord=NormalizeCoordToGECoord(geoCoord);
|
|
2734
|
+
|
|
2735
|
+
shape[j] = geoCoord;
|
|
2736
|
+
}
|
|
2737
|
+
}
|
|
2738
|
+
}
|
|
2739
|
+
|
|
2740
|
+
return shapeInfo;
|
|
2741
|
+
}
|
|
2742
|
+
|
|
2743
|
+
private static LabelToWWReady(shapeInfo: ShapeInfo,
|
|
2744
|
+
ipc: IPointConversion,
|
|
2745
|
+
normalize: boolean): ShapeInfo | null {
|
|
2746
|
+
|
|
2747
|
+
try {
|
|
2748
|
+
let coord: Point2D = new Point2D(shapeInfo.getGlyphPosition().getX(), shapeInfo.getGlyphPosition().getY()) as Point2D;
|
|
2749
|
+
let geoCoord: Point2D = ipc.PixelsToGeo(coord);
|
|
2750
|
+
//M. Deutch 9-26-11
|
|
2751
|
+
if (normalize) {
|
|
2752
|
+
geoCoord = MultiPointHandler.NormalizeCoordToGECoord(geoCoord);
|
|
2753
|
+
}
|
|
2754
|
+
let latitude: double = geoCoord.getY();
|
|
2755
|
+
let longitude: double = geoCoord.getX();
|
|
2756
|
+
let angle: number = Math.round(shapeInfo.getModifierAngle());
|
|
2757
|
+
|
|
2758
|
+
let text: string = shapeInfo.getModifierString();
|
|
2759
|
+
|
|
2760
|
+
if (text != null && text !== "") {
|
|
2761
|
+
shapeInfo.setModifierPosition(geoCoord);
|
|
2762
|
+
} else {
|
|
2763
|
+
return null;
|
|
2764
|
+
}
|
|
2765
|
+
} catch (exc) {
|
|
2766
|
+
if (exc instanceof Error) {
|
|
2767
|
+
console.error(exc.message);
|
|
2768
|
+
console.log(exc.stack);
|
|
2769
|
+
} else {
|
|
2770
|
+
throw exc;
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
|
|
2774
|
+
return shapeInfo;
|
|
2775
|
+
}
|
|
2776
|
+
|
|
2777
|
+
/**
|
|
2778
|
+
* Google earth centers text on point rather than drawing from that point.
|
|
2779
|
+
* So we need to adjust the point to where the center of the text would be.
|
|
2780
|
+
*
|
|
2781
|
+
* @param modifier
|
|
2782
|
+
*/
|
|
2783
|
+
private static AdjustModifierPointToCenter(modifier: ShapeInfo): void {
|
|
2784
|
+
let at: AffineTransform;
|
|
2785
|
+
try {
|
|
2786
|
+
let bounds2: Rectangle = modifier.getTextLayout().getBounds();
|
|
2787
|
+
let bounds: Rectangle2D = new Rectangle2D(bounds2.getX(), bounds2.getY(), bounds2.getWidth(), bounds2.getHeight());
|
|
2788
|
+
} catch (exc) {
|
|
2789
|
+
if (exc instanceof Error) {
|
|
2790
|
+
console.error(exc.message);
|
|
2791
|
+
console.log(exc.stack);
|
|
2792
|
+
} else {
|
|
2793
|
+
throw exc;
|
|
2794
|
+
}
|
|
2795
|
+
}
|
|
2796
|
+
}
|
|
2797
|
+
|
|
2798
|
+
/**
|
|
2799
|
+
*
|
|
2800
|
+
* @param shapeInfo
|
|
2801
|
+
* @param ipc
|
|
2802
|
+
* @param geMap
|
|
2803
|
+
* @param normalize
|
|
2804
|
+
* @return
|
|
2805
|
+
* @deprecated
|
|
2806
|
+
*/
|
|
2807
|
+
private static ShapeToJSONString(shapeInfo: ShapeInfo, ipc: IPointConversion, geMap: boolean, normalize: boolean): string {
|
|
2808
|
+
let JSONed: string = "";
|
|
2809
|
+
/*
|
|
2810
|
+
NOTE: Google Earth / KML colors are backwards.
|
|
2811
|
+
They are ordered Alpha,Blue,Green,Red, not Red,Green,Blue,Aplha like the rest of the world
|
|
2812
|
+
* */
|
|
2813
|
+
let fillColor: string;
|
|
2814
|
+
let lineColor: string;
|
|
2815
|
+
|
|
2816
|
+
if (shapeInfo.getLineColor() != null) {
|
|
2817
|
+
lineColor = RendererUtilities.colorToHexString(shapeInfo.getLineColor(), false).substring(1);
|
|
2818
|
+
if (geMap) {
|
|
2819
|
+
lineColor = JavaRendererUtilities.ARGBtoABGR(lineColor);
|
|
2820
|
+
}
|
|
2821
|
+
|
|
2822
|
+
}
|
|
2823
|
+
if (shapeInfo.getFillColor() != null) {
|
|
2824
|
+
fillColor = RendererUtilities.colorToHexString(shapeInfo.getFillColor(), false).substring(1);
|
|
2825
|
+
if (geMap) {
|
|
2826
|
+
fillColor = JavaRendererUtilities.ARGBtoABGR(fillColor);
|
|
2827
|
+
}
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
let stroke: BasicStroke;
|
|
2831
|
+
stroke = shapeInfo.getStroke();
|
|
2832
|
+
let lineWidth: int = 4;
|
|
2833
|
+
|
|
2834
|
+
if (stroke != null) {
|
|
2835
|
+
lineWidth = stroke.getLineWidth() as int;
|
|
2836
|
+
}
|
|
2837
|
+
|
|
2838
|
+
let shapesArray: Point2D[][] = shapeInfo.getPolylines();
|
|
2839
|
+
let n: int = shapesArray.length;
|
|
2840
|
+
//for (int i = 0; i < shapesArray.length; i++)
|
|
2841
|
+
for (let i: int = 0; i < n; i++) {
|
|
2842
|
+
let shape: Point2D[] = shapesArray[i];
|
|
2843
|
+
|
|
2844
|
+
if (fillColor != null) {
|
|
2845
|
+
JSONed += ("{\"polygon\":[");
|
|
2846
|
+
} else {
|
|
2847
|
+
JSONed += ("{\"line\":[");
|
|
2848
|
+
}
|
|
2849
|
+
|
|
2850
|
+
let t: int = shape.length;
|
|
2851
|
+
//for (int j = 0; j < shape.length; j++)
|
|
2852
|
+
for (let j: int = 0; j < t; j++) {
|
|
2853
|
+
let coord: Point2D = shape[j] as Point2D;
|
|
2854
|
+
let geoCoord: Point2D = ipc.PixelsToGeo(coord);
|
|
2855
|
+
//M. Deutch 9-27-11
|
|
2856
|
+
if (normalize) {
|
|
2857
|
+
geoCoord = MultiPointHandler.NormalizeCoordToGECoord(geoCoord);
|
|
2858
|
+
}
|
|
2859
|
+
let latitude: double = geoCoord.getY();
|
|
2860
|
+
let longitude: double = geoCoord.getX();
|
|
2861
|
+
|
|
2862
|
+
//diagnostic M. Deutch 10-18-11
|
|
2863
|
+
//set the point as geo so that the
|
|
2864
|
+
coord = new Point2D(longitude, latitude);
|
|
2865
|
+
shape[j] = coord;
|
|
2866
|
+
|
|
2867
|
+
JSONed += ("[");
|
|
2868
|
+
JSONed += (longitude);
|
|
2869
|
+
JSONed += (",");
|
|
2870
|
+
JSONed += (latitude);
|
|
2871
|
+
JSONed += ("]");
|
|
2872
|
+
|
|
2873
|
+
if (j < (shape.length - 1)) {
|
|
2874
|
+
JSONed += (",");
|
|
2875
|
+
}
|
|
2876
|
+
}
|
|
2877
|
+
|
|
2878
|
+
JSONed += ("]");
|
|
2879
|
+
if (lineColor != null) {
|
|
2880
|
+
JSONed += (",\"lineColor\":\"");
|
|
2881
|
+
JSONed += (lineColor);
|
|
2882
|
+
|
|
2883
|
+
JSONed += ("\"");
|
|
2884
|
+
}
|
|
2885
|
+
if (fillColor != null) {
|
|
2886
|
+
JSONed += (",\"fillColor\":\"");
|
|
2887
|
+
JSONed += (fillColor);
|
|
2888
|
+
JSONed += ("\"");
|
|
2889
|
+
}
|
|
2890
|
+
|
|
2891
|
+
JSONed += (",\"lineWidth\":\"");
|
|
2892
|
+
JSONed += (lineWidth.toString());
|
|
2893
|
+
JSONed += ("\"");
|
|
2894
|
+
|
|
2895
|
+
JSONed += ("}");
|
|
2896
|
+
|
|
2897
|
+
if (i < (shapesArray.length - 1)) {
|
|
2898
|
+
JSONed += (",");
|
|
2899
|
+
}
|
|
2900
|
+
}
|
|
2901
|
+
|
|
2902
|
+
return JSONed.toString();
|
|
2903
|
+
}
|
|
2904
|
+
|
|
2905
|
+
private static LabelToKMLString(shapeInfo: ShapeInfo, ipc: IPointConversion, normalize: boolean, textColor: Color): string {
|
|
2906
|
+
let kml: string = "";
|
|
2907
|
+
|
|
2908
|
+
//Point2D coord = (Point2D) new Point2D(shapeInfo.getGlyphPosition().getX(), shapeInfo.getGlyphPosition().getY());
|
|
2909
|
+
let coord: Point2D = new Point2D(shapeInfo.getModifierPosition().getX(), shapeInfo.getModifierPosition().getY()) as Point2D;
|
|
2910
|
+
let geoCoord: Point2D = ipc.PixelsToGeo(coord);
|
|
2911
|
+
//M. Deutch 9-26-11
|
|
2912
|
+
if (normalize) {
|
|
2913
|
+
geoCoord = MultiPointHandler.NormalizeCoordToGECoord(geoCoord);
|
|
2914
|
+
}
|
|
2915
|
+
let latitude: double = Math.round(geoCoord.getY() * 100000000.0) / 100000000.0;
|
|
2916
|
+
let longitude: double = Math.round(geoCoord.getX() * 100000000.0) / 100000000.0;
|
|
2917
|
+
let angle: number = Math.round(shapeInfo.getModifierAngle());
|
|
2918
|
+
|
|
2919
|
+
let text: string = shapeInfo.getModifierString();
|
|
2920
|
+
|
|
2921
|
+
let cdataStart: string = "<![CDATA[";
|
|
2922
|
+
let cdataEnd: string = "]]>";
|
|
2923
|
+
|
|
2924
|
+
let color: string = RendererUtilities.colorToHexString(textColor, false).substring(1);
|
|
2925
|
+
color = JavaRendererUtilities.ARGBtoABGR(color);
|
|
2926
|
+
let kmlScale: double = RendererSettings.getInstance().getKMLLabelScale();
|
|
2927
|
+
|
|
2928
|
+
if (kmlScale > 0 && text != null && text !== "") {
|
|
2929
|
+
kml += ("<Placemark>");//("<Placemark id=\"" + id + "_lp" + i + "\">");
|
|
2930
|
+
kml += ("<name>" + cdataStart + text + cdataEnd + "</name>");
|
|
2931
|
+
kml += ("<Style>");
|
|
2932
|
+
kml += ("<IconStyle>");
|
|
2933
|
+
kml += ("<scale>" + kmlScale + "</scale>");
|
|
2934
|
+
kml += ("<heading>" + angle + "</heading>");
|
|
2935
|
+
kml += ("<Icon>");
|
|
2936
|
+
kml += ("<href></href>");
|
|
2937
|
+
kml += ("</Icon>");
|
|
2938
|
+
kml += ("</IconStyle>");
|
|
2939
|
+
kml += ("<LabelStyle>");
|
|
2940
|
+
kml += ("<color>" + color + "</color>");
|
|
2941
|
+
kml += ("<scale>" + kmlScale.toString() + "</scale>");
|
|
2942
|
+
kml += ("</LabelStyle>");
|
|
2943
|
+
kml += ("</Style>");
|
|
2944
|
+
kml += ("<Point>");
|
|
2945
|
+
kml += ("<extrude>1</extrude>");
|
|
2946
|
+
kml += ("<altitudeMode>relativeToGround</altitudeMode>");
|
|
2947
|
+
kml += ("<coordinates>");
|
|
2948
|
+
kml += (longitude);
|
|
2949
|
+
kml += (",");
|
|
2950
|
+
kml += (latitude);
|
|
2951
|
+
kml += ("</coordinates>");
|
|
2952
|
+
kml += ("</Point>");
|
|
2953
|
+
kml += ("</Placemark>");
|
|
2954
|
+
} else {
|
|
2955
|
+
return "";
|
|
2956
|
+
}
|
|
2957
|
+
|
|
2958
|
+
return kml.toString();
|
|
2959
|
+
}
|
|
2960
|
+
|
|
2961
|
+
/**
|
|
2962
|
+
*
|
|
2963
|
+
* @param shapeInfo
|
|
2964
|
+
* @param ipc
|
|
2965
|
+
* @param normalize
|
|
2966
|
+
* @return
|
|
2967
|
+
* @deprecated
|
|
2968
|
+
*/
|
|
2969
|
+
private static LabelToJSONString(shapeInfo: ShapeInfo, ipc: IPointConversion, normalize: boolean): string {
|
|
2970
|
+
let JSONed: string = "";
|
|
2971
|
+
/*
|
|
2972
|
+
NOTE: Google Earth / KML colors are backwards.
|
|
2973
|
+
They are ordered Alpha,Blue,Green,Red, not Red,Green,Blue,Aplha like the rest of the world
|
|
2974
|
+
* */
|
|
2975
|
+
JSONed += ("{\"label\":");
|
|
2976
|
+
|
|
2977
|
+
let coord: Point2D = new Point2D(shapeInfo.getGlyphPosition().getX(), shapeInfo.getGlyphPosition().getY()) as Point2D;
|
|
2978
|
+
let geoCoord: Point2D = ipc.PixelsToGeo(coord);
|
|
2979
|
+
if (normalize) {
|
|
2980
|
+
geoCoord = MultiPointHandler.NormalizeCoordToGECoord(geoCoord);
|
|
2981
|
+
}
|
|
2982
|
+
let latitude: double = geoCoord.getY();
|
|
2983
|
+
let longitude: double = geoCoord.getX();
|
|
2984
|
+
let angle: double = shapeInfo.getModifierAngle();
|
|
2985
|
+
coord.setLocation(longitude, latitude);
|
|
2986
|
+
|
|
2987
|
+
shapeInfo.setGlyphPosition(coord);
|
|
2988
|
+
|
|
2989
|
+
let text: string = shapeInfo.getModifierString();
|
|
2990
|
+
|
|
2991
|
+
if (text != null && text !== "") {
|
|
2992
|
+
JSONed += ("[");
|
|
2993
|
+
JSONed += (longitude);
|
|
2994
|
+
JSONed += (",");
|
|
2995
|
+
JSONed += (latitude);
|
|
2996
|
+
JSONed += ("]");
|
|
2997
|
+
|
|
2998
|
+
JSONed += (",\"text\":\"");
|
|
2999
|
+
JSONed += (text);
|
|
3000
|
+
JSONed += ("\"");
|
|
3001
|
+
|
|
3002
|
+
JSONed += (",\"angle\":\"");
|
|
3003
|
+
JSONed += (angle);
|
|
3004
|
+
JSONed += ("\"}");
|
|
3005
|
+
} else {
|
|
3006
|
+
return "";
|
|
3007
|
+
}
|
|
3008
|
+
|
|
3009
|
+
return JSONed.toString();
|
|
3010
|
+
}
|
|
3011
|
+
|
|
3012
|
+
public static canRenderMultiPoint(symbolID: string, modifiers: Map<string, string>, numPoints: int): string {
|
|
3013
|
+
try {
|
|
3014
|
+
let basicID: string = SymbolUtilities.getBasicSymbolID(symbolID);
|
|
3015
|
+
let info: MSInfo = MSLookup.getInstance().getMSLInfo(symbolID);
|
|
3016
|
+
|
|
3017
|
+
if (info == null) {
|
|
3018
|
+
if (SymbolID.getVersion(symbolID) === SymbolID.Version_2525E) {
|
|
3019
|
+
return "Basic ID: " + basicID + " not recognized in version E (13)";
|
|
3020
|
+
} else {
|
|
3021
|
+
return "Basic ID: " + basicID + " not recognized in version D (11)";
|
|
3022
|
+
}
|
|
3023
|
+
}
|
|
3024
|
+
|
|
3025
|
+
let drawRule: int = info.getDrawRule();
|
|
3026
|
+
|
|
3027
|
+
if (drawRule === DrawRules.DONOTDRAW) {
|
|
3028
|
+
return "Basic ID: " + basicID + " has no draw rule";
|
|
3029
|
+
} else if (!SymbolUtilities.isMultiPoint(symbolID)) {
|
|
3030
|
+
return "Basic ID: " + basicID + " is not a multipoint symbol";
|
|
3031
|
+
} else if (numPoints < info.getMinPointCount()) {
|
|
3032
|
+
return "Basic ID: " + basicID + " requires a minimum of " + info.getMinPointCount().toString() + " points. " + numPoints.toString() + " are present.";
|
|
3033
|
+
}
|
|
3034
|
+
|
|
3035
|
+
//now check for required modifiers
|
|
3036
|
+
let AM: Array<number> = new Array();
|
|
3037
|
+
let AN: Array<number> = new Array();
|
|
3038
|
+
if (modifiers.has(Modifiers.AM_DISTANCE)) {
|
|
3039
|
+
let amArray: string[] = modifiers.get(Modifiers.AM_DISTANCE).split(",");
|
|
3040
|
+
for (let str of amArray) {
|
|
3041
|
+
if (str !== "") {
|
|
3042
|
+
AM.push(parseFloat(str));
|
|
3043
|
+
}
|
|
3044
|
+
}
|
|
3045
|
+
}
|
|
3046
|
+
if (modifiers.has(Modifiers.AN_AZIMUTH)) {
|
|
3047
|
+
let anArray: string[] = modifiers.get(Modifiers.AN_AZIMUTH).split(",");
|
|
3048
|
+
for (let str of anArray) {
|
|
3049
|
+
if (str !== "") {
|
|
3050
|
+
AN.push(parseFloat(str));
|
|
3051
|
+
}
|
|
3052
|
+
}
|
|
3053
|
+
}
|
|
3054
|
+
|
|
3055
|
+
return MultiPointHandler.hasRequiredModifiers(symbolID, drawRule, AM, AN);
|
|
3056
|
+
} catch (exc) {
|
|
3057
|
+
if (exc instanceof Error) {
|
|
3058
|
+
ErrorLogger.LogException("MultiPointHandler", "canRenderMultiPoint", exc);
|
|
3059
|
+
return "false: " + exc.message;
|
|
3060
|
+
} else {
|
|
3061
|
+
throw exc;
|
|
3062
|
+
}
|
|
3063
|
+
}
|
|
3064
|
+
}
|
|
3065
|
+
|
|
3066
|
+
private static hasRequiredModifiers(symbolID: string, drawRule: int, AM: Array<number>, AN: Array<number>): string {
|
|
3067
|
+
|
|
3068
|
+
let message: string = symbolID;
|
|
3069
|
+
try {
|
|
3070
|
+
if (drawRule > 700) {
|
|
3071
|
+
if (drawRule === DrawRules.CIRCULAR1) {
|
|
3072
|
+
if (AM != null && AM.length > 0) {
|
|
3073
|
+
return "true";
|
|
3074
|
+
} else {
|
|
3075
|
+
message += " requires a modifiers object that has 1 distance/AM value.";
|
|
3076
|
+
return message;
|
|
3077
|
+
}
|
|
3078
|
+
} else {
|
|
3079
|
+
if (drawRule === DrawRules.RECTANGULAR2) {
|
|
3080
|
+
if (AM != null && AM.length >= 2
|
|
3081
|
+
&& AN != null && AN.length >= 1) {
|
|
3082
|
+
return "true";
|
|
3083
|
+
} else {
|
|
3084
|
+
message += (" requires a modifiers object that has 2 distance/AM values and 1 azimuth/AN value.");
|
|
3085
|
+
return message;
|
|
3086
|
+
}
|
|
3087
|
+
} else {
|
|
3088
|
+
if (drawRule === DrawRules.ARC1) {
|
|
3089
|
+
if (AM != null && AM.length >= 1
|
|
3090
|
+
&& AN != null && AN.length >= 2) {
|
|
3091
|
+
return "true";
|
|
3092
|
+
} else {
|
|
3093
|
+
message += (" requires a modifiers object that has 2 distance/AM values and 2 azimuth/AN values per sector. The first sector can have just one AM value although it is recommended to always use 2 values for each sector.");
|
|
3094
|
+
return message;
|
|
3095
|
+
}
|
|
3096
|
+
} else {
|
|
3097
|
+
if (drawRule === DrawRules.CIRCULAR2) {
|
|
3098
|
+
if (AM != null && AM.length > 0) {
|
|
3099
|
+
return "true";
|
|
3100
|
+
} else {
|
|
3101
|
+
message += (" requires a modifiers object that has at least 1 distance/AM value");
|
|
3102
|
+
return message;
|
|
3103
|
+
}
|
|
3104
|
+
} else {
|
|
3105
|
+
if (drawRule === DrawRules.RECTANGULAR1) {
|
|
3106
|
+
if (AM != null && AM.length > 0) {
|
|
3107
|
+
return "true";
|
|
3108
|
+
} else {
|
|
3109
|
+
message += (" requires a modifiers object that has 1 distance/AM value.");
|
|
3110
|
+
return message;
|
|
3111
|
+
}
|
|
3112
|
+
} else {
|
|
3113
|
+
if (drawRule === DrawRules.ELLIPSE1) {
|
|
3114
|
+
if (AM != null && AM.length >= 2
|
|
3115
|
+
&& AN != null && AN.length >= 1) {
|
|
3116
|
+
return "true";
|
|
3117
|
+
} else {
|
|
3118
|
+
message += (" requires a modifiers object that has 2 distance/AM values and 1 azimuth/AN value.");
|
|
3119
|
+
return message;
|
|
3120
|
+
}
|
|
3121
|
+
}
|
|
3122
|
+
else {
|
|
3123
|
+
if (drawRule === DrawRules.RECTANGULAR3) {
|
|
3124
|
+
if (AM != null && AM.length >= 1) {
|
|
3125
|
+
return "true";
|
|
3126
|
+
} else {
|
|
3127
|
+
message += (" requires a modifiers object that has 1 distance/AM value.");
|
|
3128
|
+
return message;
|
|
3129
|
+
}
|
|
3130
|
+
} else {
|
|
3131
|
+
//should never get here
|
|
3132
|
+
return "true";
|
|
3133
|
+
}
|
|
3134
|
+
}
|
|
3135
|
+
|
|
3136
|
+
}
|
|
3137
|
+
|
|
3138
|
+
}
|
|
3139
|
+
|
|
3140
|
+
}
|
|
3141
|
+
|
|
3142
|
+
}
|
|
3143
|
+
|
|
3144
|
+
}
|
|
3145
|
+
|
|
3146
|
+
} else {
|
|
3147
|
+
if (drawRule === DrawRules.POINT17) {
|
|
3148
|
+
if (AM != null && AM.length >= 2
|
|
3149
|
+
&& AN != null && AN.length >= 1) {
|
|
3150
|
+
return "true";
|
|
3151
|
+
} else {
|
|
3152
|
+
message += (" requires a modifiers object that has 2 distance/AM values and 1 azimuth/AN value.");
|
|
3153
|
+
return message;
|
|
3154
|
+
}
|
|
3155
|
+
} else {
|
|
3156
|
+
if (drawRule === DrawRules.POINT18) {
|
|
3157
|
+
if (AM != null && AM.length >= 2
|
|
3158
|
+
&& AN != null && AN.length >= 2) {
|
|
3159
|
+
return "true";
|
|
3160
|
+
} else {
|
|
3161
|
+
message += (" requires a modifiers object that has 2 distance/AM values and 2 azimuth/AN values.");
|
|
3162
|
+
return message;
|
|
3163
|
+
}
|
|
3164
|
+
} else {
|
|
3165
|
+
if (drawRule === DrawRules.CORRIDOR1) {
|
|
3166
|
+
if (AM != null && AM.length > 0) {
|
|
3167
|
+
return "true";
|
|
3168
|
+
} else {
|
|
3169
|
+
message += (" requires a modifiers object that has 1 distance/AM value.");
|
|
3170
|
+
return message;
|
|
3171
|
+
}
|
|
3172
|
+
} else {
|
|
3173
|
+
//no required parameters
|
|
3174
|
+
return "true";
|
|
3175
|
+
}
|
|
3176
|
+
}
|
|
3177
|
+
|
|
3178
|
+
}
|
|
3179
|
+
|
|
3180
|
+
}
|
|
3181
|
+
|
|
3182
|
+
} catch (exc) {
|
|
3183
|
+
if (exc instanceof Error) {
|
|
3184
|
+
ErrorLogger.LogException("MultiPointHandler", "hasRequiredModifiers", exc);
|
|
3185
|
+
return "true";
|
|
3186
|
+
} else {
|
|
3187
|
+
throw exc;
|
|
3188
|
+
}
|
|
3189
|
+
}
|
|
3190
|
+
}
|
|
3191
|
+
|
|
3192
|
+
/**
|
|
3193
|
+
*
|
|
3194
|
+
* @param id
|
|
3195
|
+
* @param name
|
|
3196
|
+
* @param description
|
|
3197
|
+
* @param basicShapeType
|
|
3198
|
+
* @param controlPoints
|
|
3199
|
+
* @param scale
|
|
3200
|
+
* @param bbox
|
|
3201
|
+
* @param symbolModifiers
|
|
3202
|
+
* @param symbolAttributes
|
|
3203
|
+
* @return
|
|
3204
|
+
*/
|
|
3205
|
+
public static RenderBasicShapeAsMilStdSymbol(id: string,
|
|
3206
|
+
name: string,
|
|
3207
|
+
description: string,
|
|
3208
|
+
basicShapeType: int,
|
|
3209
|
+
controlPoints: string,
|
|
3210
|
+
scale: number,
|
|
3211
|
+
bbox: string,
|
|
3212
|
+
symbolModifiers: Map<string, string>,
|
|
3213
|
+
symbolAttributes: Map<string, string>): MilStdSymbol
|
|
3214
|
+
{
|
|
3215
|
+
let mSymbol: MilStdSymbol;
|
|
3216
|
+
let normalize: boolean = true;
|
|
3217
|
+
let controlLat: number = 0.0;
|
|
3218
|
+
let controlLong: number = 0.0;
|
|
3219
|
+
//String jsonContent = "";
|
|
3220
|
+
|
|
3221
|
+
let rect: Rectangle;
|
|
3222
|
+
|
|
3223
|
+
//for symbol & line fill
|
|
3224
|
+
let tgPoints: Array<POINT2>;
|
|
3225
|
+
|
|
3226
|
+
let coordinates: string[] = controlPoints.split(" ");
|
|
3227
|
+
let shapes: Array<ShapeInfo>;//new ArrayList<ShapeInfo>();
|
|
3228
|
+
let modifiers: Array<ShapeInfo>;//new ArrayList<ShapeInfo>();
|
|
3229
|
+
//ArrayList<Point2D> pixels = new ArrayList<Point2D>();
|
|
3230
|
+
let geoCoords: Array<Point2D> = new Array<Point2D>();
|
|
3231
|
+
let len: int = coordinates.length;
|
|
3232
|
+
|
|
3233
|
+
let ipc: IPointConversion;
|
|
3234
|
+
|
|
3235
|
+
//Deutch moved section 6-29-11
|
|
3236
|
+
let left: number = 0.0;
|
|
3237
|
+
let right: number = 0.0;
|
|
3238
|
+
let top: number = 0.0;
|
|
3239
|
+
let bottom: number = 0.0;
|
|
3240
|
+
let temp: Point2D;
|
|
3241
|
+
let ptGeoUL: Point2D;
|
|
3242
|
+
let width: int = 0;
|
|
3243
|
+
let height: int = 0;
|
|
3244
|
+
let leftX: int = 0;
|
|
3245
|
+
let topY: int = 0;
|
|
3246
|
+
let bottomY: int = 0;
|
|
3247
|
+
let rightX: int = 0;
|
|
3248
|
+
let j: int = 0;
|
|
3249
|
+
let bboxCoords: Array<Point2D>;
|
|
3250
|
+
if (bbox != null && bbox !== "") {
|
|
3251
|
+
let bounds: string[];
|
|
3252
|
+
if (bbox.includes(" "))//trapezoid
|
|
3253
|
+
{
|
|
3254
|
+
bboxCoords = new Array<Point2D>();
|
|
3255
|
+
let x: double = 0;
|
|
3256
|
+
let y: double = 0;
|
|
3257
|
+
let coords: string[] = bbox.split(" ");
|
|
3258
|
+
let arrCoord: string[];
|
|
3259
|
+
for (let coord of coords) {
|
|
3260
|
+
arrCoord = coord.split(",");
|
|
3261
|
+
x = parseFloat(arrCoord[0]);
|
|
3262
|
+
y = parseFloat(arrCoord[1]);
|
|
3263
|
+
bboxCoords.push(new Point2D(x, y));
|
|
3264
|
+
}
|
|
3265
|
+
//use the upper left corner of the MBR containing geoCoords
|
|
3266
|
+
//to set the converter
|
|
3267
|
+
ptGeoUL = MultiPointHandler.getGeoUL(bboxCoords);
|
|
3268
|
+
left = ptGeoUL.getX();
|
|
3269
|
+
top = ptGeoUL.getY();
|
|
3270
|
+
ipc = new PointConverter(left, top, scale);
|
|
3271
|
+
let ptPixels: Point2D;
|
|
3272
|
+
let ptGeo: Point2D;
|
|
3273
|
+
let n: int = bboxCoords.length;
|
|
3274
|
+
//for (j = 0; j < bboxCoords.length; j++)
|
|
3275
|
+
for (j = 0; j < n; j++) {
|
|
3276
|
+
ptGeo = bboxCoords[j];
|
|
3277
|
+
ptPixels = ipc.GeoToPixels(ptGeo);
|
|
3278
|
+
x = ptPixels.getX();
|
|
3279
|
+
y = ptPixels.getY();
|
|
3280
|
+
if (x < 20) {
|
|
3281
|
+
x = 20;
|
|
3282
|
+
}
|
|
3283
|
+
if (y < 20) {
|
|
3284
|
+
y = 20;
|
|
3285
|
+
}
|
|
3286
|
+
ptPixels.setLocation(x, y);
|
|
3287
|
+
//end section
|
|
3288
|
+
bboxCoords[j] = ptPixels;
|
|
3289
|
+
}
|
|
3290
|
+
} else//rectangle
|
|
3291
|
+
{
|
|
3292
|
+
bounds = bbox.split(",");
|
|
3293
|
+
left = parseFloat(bounds[0]);
|
|
3294
|
+
right = parseFloat(bounds[2]);
|
|
3295
|
+
top = parseFloat(bounds[3]);
|
|
3296
|
+
bottom = parseFloat(bounds[1]);
|
|
3297
|
+
scale = MultiPointHandler.getReasonableScale(bbox, scale);
|
|
3298
|
+
ipc = new PointConverter(left, top, scale);
|
|
3299
|
+
}
|
|
3300
|
+
|
|
3301
|
+
let pt2d: Point2D;
|
|
3302
|
+
if (bboxCoords == null) {
|
|
3303
|
+
pt2d = new Point2D(left, top);
|
|
3304
|
+
temp = ipc.GeoToPixels(pt2d);
|
|
3305
|
+
|
|
3306
|
+
leftX = temp.getX() as int;
|
|
3307
|
+
topY = temp.getY() as int;
|
|
3308
|
+
|
|
3309
|
+
pt2d = new Point2D(right, bottom);
|
|
3310
|
+
temp = ipc.GeoToPixels(pt2d);
|
|
3311
|
+
|
|
3312
|
+
bottomY = temp.getY() as int;
|
|
3313
|
+
rightX = temp.getX() as int;
|
|
3314
|
+
//diagnostic clipping does not work for large scales
|
|
3315
|
+
// if (scale > 10e6) {
|
|
3316
|
+
// //get widest point in the AOI
|
|
3317
|
+
// double midLat = 0;
|
|
3318
|
+
// if (bottom < 0 && top > 0) {
|
|
3319
|
+
// midLat = 0;
|
|
3320
|
+
// } else if (bottom < 0 && top < 0) {
|
|
3321
|
+
// midLat = top;
|
|
3322
|
+
// } else if (bottom > 0 && top > 0) {
|
|
3323
|
+
// midLat = bottom;
|
|
3324
|
+
// }
|
|
3325
|
+
//
|
|
3326
|
+
// temp = ipc.GeoToPixels(new Point2D(right, midLat));
|
|
3327
|
+
// rightX = (int) temp.getX();
|
|
3328
|
+
// }
|
|
3329
|
+
//end section
|
|
3330
|
+
|
|
3331
|
+
width = Math.abs(rightX - leftX) as int;
|
|
3332
|
+
height = Math.abs(bottomY - topY) as int;
|
|
3333
|
+
|
|
3334
|
+
if (width === 0 || height === 0) {
|
|
3335
|
+
|
|
3336
|
+
rect = null;
|
|
3337
|
+
}
|
|
3338
|
+
|
|
3339
|
+
else {
|
|
3340
|
+
|
|
3341
|
+
rect = new Rectangle(leftX, topY, width, height);
|
|
3342
|
+
}
|
|
3343
|
+
|
|
3344
|
+
}
|
|
3345
|
+
} else {
|
|
3346
|
+
rect = null;
|
|
3347
|
+
}
|
|
3348
|
+
//end section
|
|
3349
|
+
|
|
3350
|
+
for (let i: int = 0; i < len; i++) {
|
|
3351
|
+
let coordPair: string[] = coordinates[i].split(",");
|
|
3352
|
+
let latitude: number = parseFloat(coordPair[1].trim());
|
|
3353
|
+
let longitude: number = parseFloat(coordPair[0].trim());
|
|
3354
|
+
geoCoords.push(new Point2D(longitude, latitude));
|
|
3355
|
+
}
|
|
3356
|
+
if (ipc == null) {
|
|
3357
|
+
let ptCoordsUL: Point2D = MultiPointHandler.getGeoUL(geoCoords);
|
|
3358
|
+
ipc = new PointConverter(ptCoordsUL.getX(), ptCoordsUL.getY(), scale);
|
|
3359
|
+
}
|
|
3360
|
+
//if (crossesIDL(geoCoords) == true)
|
|
3361
|
+
// if(Math.abs(right-left)>180)
|
|
3362
|
+
// {
|
|
3363
|
+
// normalize = true;
|
|
3364
|
+
// ((PointConverter)ipc).set_normalize(true);
|
|
3365
|
+
// }
|
|
3366
|
+
// else {
|
|
3367
|
+
// normalize = false;
|
|
3368
|
+
// ((PointConverter)ipc).set_normalize(false);
|
|
3369
|
+
// }
|
|
3370
|
+
|
|
3371
|
+
//seems to work ok at world view
|
|
3372
|
+
// if (normalize) {
|
|
3373
|
+
// NormalizeGECoordsToGEExtents(0, 360, geoCoords);
|
|
3374
|
+
// }
|
|
3375
|
+
|
|
3376
|
+
//M. Deutch 10-3-11
|
|
3377
|
+
//must shift the rect pixels to synch with the new ipc
|
|
3378
|
+
//the old ipc was in synch with the bbox, so rect x,y was always 0,0
|
|
3379
|
+
//the new ipc synchs with the upper left of the geocoords so the boox is shifted
|
|
3380
|
+
//and therefore the clipping rectangle must shift by the delta x,y between
|
|
3381
|
+
//the upper left corner of the original bbox and the upper left corner of the geocoords
|
|
3382
|
+
let geoCoords2: Array<Point2D> = new Array<Point2D>();
|
|
3383
|
+
geoCoords2.push(new Point2D(left, top));
|
|
3384
|
+
geoCoords2.push(new Point2D(right, bottom));
|
|
3385
|
+
|
|
3386
|
+
// if (normalize) {
|
|
3387
|
+
// NormalizeGECoordsToGEExtents(0, 360, geoCoords2);
|
|
3388
|
+
// }
|
|
3389
|
+
|
|
3390
|
+
//disable clipping
|
|
3391
|
+
if (MultiPointHandler.crossesIDL(geoCoords) === false) {
|
|
3392
|
+
rect = null;
|
|
3393
|
+
bboxCoords = null;
|
|
3394
|
+
}
|
|
3395
|
+
|
|
3396
|
+
let symbolCode = "";
|
|
3397
|
+
try {
|
|
3398
|
+
let fillColor: string;
|
|
3399
|
+
mSymbol = new MilStdSymbol(symbolCode, null, geoCoords, null);
|
|
3400
|
+
|
|
3401
|
+
// mSymbol.setUseDashArray(true);
|
|
3402
|
+
|
|
3403
|
+
if (symbolModifiers != null || symbolAttributes != null) {
|
|
3404
|
+
MultiPointHandler.populateModifiers(symbolModifiers, symbolAttributes, mSymbol);
|
|
3405
|
+
} else {
|
|
3406
|
+
mSymbol.setFillColor(null);
|
|
3407
|
+
}
|
|
3408
|
+
|
|
3409
|
+
if (mSymbol.getFillColor() != null) {
|
|
3410
|
+
let fc: Color = mSymbol.getFillColor();
|
|
3411
|
+
fillColor = RendererUtilities.colorToHexString(fc, false);
|
|
3412
|
+
|
|
3413
|
+
}
|
|
3414
|
+
|
|
3415
|
+
let tg: TGLight = clsRenderer.createTGLightFromMilStdSymbolBasicShape(mSymbol, ipc, basicShapeType);
|
|
3416
|
+
let shapeInfos: Array<ShapeInfo> = [];
|
|
3417
|
+
let modifierShapeInfos: Array<ShapeInfo> = [];
|
|
3418
|
+
let clipArea: Point2D[] | Rectangle | Rectangle2D;
|
|
3419
|
+
if (bboxCoords == null) {
|
|
3420
|
+
clipArea = rect;
|
|
3421
|
+
} else {
|
|
3422
|
+
clipArea = bboxCoords;
|
|
3423
|
+
}
|
|
3424
|
+
if (clsRenderer.intersectsClipArea(tg, ipc, clipArea)) {
|
|
3425
|
+
clsRenderer.render_GE(tg, shapeInfos, modifierShapeInfos, ipc, clipArea);
|
|
3426
|
+
}
|
|
3427
|
+
mSymbol.setSymbolShapes(shapeInfos);
|
|
3428
|
+
mSymbol.setModifierShapes(modifierShapeInfos);
|
|
3429
|
+
mSymbol.set_WasClipped(tg.get_WasClipped());
|
|
3430
|
+
shapes = mSymbol.getSymbolShapes();
|
|
3431
|
+
modifiers = mSymbol.getModifierShapes();
|
|
3432
|
+
|
|
3433
|
+
//convert points////////////////////////////////////////////////////
|
|
3434
|
+
let polylines: Array<Array<Point2D>>;
|
|
3435
|
+
let newPolylines: Array<Array<Point2D>>;
|
|
3436
|
+
let newLine: Array<Point2D>;
|
|
3437
|
+
for (let shape of shapes) {
|
|
3438
|
+
polylines = shape.getPolylines();
|
|
3439
|
+
//console.log("pixel polylines: " + polylines.toString());
|
|
3440
|
+
newPolylines = MultiPointHandler.ConvertPolylinePixelsToCoords(polylines, ipc, normalize);
|
|
3441
|
+
shape.setPolylines(newPolylines);
|
|
3442
|
+
}
|
|
3443
|
+
|
|
3444
|
+
for (let label of modifiers) {
|
|
3445
|
+
let pixelCoord: Point2D = label.getModifierPosition();
|
|
3446
|
+
if (pixelCoord == null) {
|
|
3447
|
+
pixelCoord = label.getGlyphPosition();
|
|
3448
|
+
}
|
|
3449
|
+
let geoCoord: Point2D = ipc.PixelsToGeo(pixelCoord);
|
|
3450
|
+
|
|
3451
|
+
if (normalize) {
|
|
3452
|
+
geoCoord = MultiPointHandler.NormalizeCoordToGECoord(geoCoord);
|
|
3453
|
+
}
|
|
3454
|
+
|
|
3455
|
+
let latitude: double = geoCoord.getY();
|
|
3456
|
+
let longitude: double = geoCoord.getX();
|
|
3457
|
+
label.setModifierPosition(new Point2D(longitude, latitude));
|
|
3458
|
+
|
|
3459
|
+
}
|
|
3460
|
+
|
|
3461
|
+
////////////////////////////////////////////////////////////////////
|
|
3462
|
+
mSymbol.setModifierShapes(modifiers);
|
|
3463
|
+
mSymbol.setSymbolShapes(shapes);
|
|
3464
|
+
|
|
3465
|
+
} catch (exc) {
|
|
3466
|
+
if (exc instanceof Error) {
|
|
3467
|
+
console.log(exc.message);
|
|
3468
|
+
console.log("Symbol Code: " + symbolCode);
|
|
3469
|
+
console.log(exc.stack);
|
|
3470
|
+
} else {
|
|
3471
|
+
throw exc;
|
|
3472
|
+
}
|
|
3473
|
+
}
|
|
3474
|
+
|
|
3475
|
+
/*
|
|
3476
|
+
let debug: boolean = false;
|
|
3477
|
+
if (debug === true) {
|
|
3478
|
+
console.log("Symbol Code: " + symbolCode);
|
|
3479
|
+
console.log("Scale: " + scale);
|
|
3480
|
+
console.log("BBOX: " + bbox);
|
|
3481
|
+
if (controlPoints != null) {
|
|
3482
|
+
console.log("Geo Points: " + controlPoints);
|
|
3483
|
+
}
|
|
3484
|
+
if (tgl != null && tgl.get_Pixels() != null)//pixels != null
|
|
3485
|
+
{
|
|
3486
|
+
//console.log("Pixel: " + pixels.toString());
|
|
3487
|
+
console.log("Pixel: " + tgl.get_Pixels().toString());
|
|
3488
|
+
}
|
|
3489
|
+
if (bbox != null) {
|
|
3490
|
+
console.log("geo bounds: " + bbox);
|
|
3491
|
+
}
|
|
3492
|
+
if (rect != null) {
|
|
3493
|
+
console.log("pixel bounds: " + rect.toString());
|
|
3494
|
+
}
|
|
3495
|
+
}
|
|
3496
|
+
*/
|
|
3497
|
+
|
|
3498
|
+
return mSymbol;
|
|
3499
|
+
|
|
3500
|
+
}
|
|
3501
|
+
|
|
3502
|
+
/**
|
|
3503
|
+
*
|
|
3504
|
+
* @param id
|
|
3505
|
+
* @param name
|
|
3506
|
+
* @param description
|
|
3507
|
+
* @param basicShapeType
|
|
3508
|
+
* @param controlPoints
|
|
3509
|
+
* @param scale
|
|
3510
|
+
* @param bbox
|
|
3511
|
+
* @param symbolModifiers {@link Map}, keyed using constants from
|
|
3512
|
+
* Modifiers. Pass in comma delimited String for modifiers with multiple
|
|
3513
|
+
* values like AM, AN & X
|
|
3514
|
+
* @param symbolAttributes {@link Map}, keyed using constants from
|
|
3515
|
+
* MilStdAttributes. pass in double[] for AM, AN and X; Strings for the
|
|
3516
|
+
* rest.
|
|
3517
|
+
* @param format
|
|
3518
|
+
* @return
|
|
3519
|
+
*/
|
|
3520
|
+
public static RenderBasicShape(id: string,
|
|
3521
|
+
name: string,
|
|
3522
|
+
description: string,
|
|
3523
|
+
basicShapeType: int,
|
|
3524
|
+
controlPoints: string,
|
|
3525
|
+
scale: number,
|
|
3526
|
+
bbox: string,
|
|
3527
|
+
symbolModifiers: Map<string, string>,
|
|
3528
|
+
symbolAttributes: Map<string, string>,
|
|
3529
|
+
format: int): string
|
|
3530
|
+
{
|
|
3531
|
+
let normalize: boolean = true;
|
|
3532
|
+
//Double controlLat = 0.0;
|
|
3533
|
+
//Double controlLong = 0.0;
|
|
3534
|
+
//Double metPerPix = GeoPixelConversion.metersPerPixel(scale);
|
|
3535
|
+
//String bbox2=getBoundingRectangle(controlPoints,bbox);
|
|
3536
|
+
let jsonOutput: string = "";
|
|
3537
|
+
let jsonContent: string = "";
|
|
3538
|
+
|
|
3539
|
+
let rect: Rectangle;
|
|
3540
|
+
let coordinates: string[] = controlPoints.split(" ");
|
|
3541
|
+
let shapes: Array<ShapeInfo> = new Array<ShapeInfo>();
|
|
3542
|
+
let modifiers: Array<ShapeInfo> = new Array<ShapeInfo>();
|
|
3543
|
+
//ArrayList<Point2D> pixels = new ArrayList<Point2D>();
|
|
3544
|
+
let geoCoords: Array<Point2D> = new Array<Point2D>();
|
|
3545
|
+
let len: int = coordinates.length;
|
|
3546
|
+
//diagnostic create geoCoords here
|
|
3547
|
+
let coordsUL: Point2D = null;
|
|
3548
|
+
const symbolCode = "";
|
|
3549
|
+
|
|
3550
|
+
for (let i: int = 0; i < len; i++) {
|
|
3551
|
+
let coordPair: string[] = coordinates[i].split(",");
|
|
3552
|
+
let latitude: number = parseFloat(coordPair[1].trim());
|
|
3553
|
+
let longitude: number = parseFloat(coordPair[0].trim());
|
|
3554
|
+
geoCoords.push(new Point2D(longitude, latitude));
|
|
3555
|
+
}
|
|
3556
|
+
let tgPoints: Array<POINT2>;
|
|
3557
|
+
let ipc: IPointConversion;
|
|
3558
|
+
|
|
3559
|
+
//Deutch moved section 6-29-11
|
|
3560
|
+
let left: number = 0.0;
|
|
3561
|
+
let right: number = 0.0;
|
|
3562
|
+
let top: number = 0.0;
|
|
3563
|
+
let bottom: number = 0.0;
|
|
3564
|
+
let temp: Point2D;
|
|
3565
|
+
let ptGeoUL: Point2D;
|
|
3566
|
+
let width: int = 0;
|
|
3567
|
+
let height: int = 0;
|
|
3568
|
+
let leftX: int = 0;
|
|
3569
|
+
let topY: int = 0;
|
|
3570
|
+
let bottomY: int = 0;
|
|
3571
|
+
let rightX: int = 0;
|
|
3572
|
+
let j: int = 0;
|
|
3573
|
+
let bboxCoords: Array<Point2D>;
|
|
3574
|
+
if (bbox != null && bbox !== "") {
|
|
3575
|
+
let bounds: string[];
|
|
3576
|
+
if (bbox.includes(" "))//trapezoid
|
|
3577
|
+
{
|
|
3578
|
+
bboxCoords = new Array<Point2D>();
|
|
3579
|
+
let x: double = 0;
|
|
3580
|
+
let y: double = 0;
|
|
3581
|
+
let coords: string[] = bbox.split(" ");
|
|
3582
|
+
let arrCoord: string[];
|
|
3583
|
+
for (let coord of coords) {
|
|
3584
|
+
arrCoord = coord.split(",");
|
|
3585
|
+
x = parseFloat(arrCoord[0]);
|
|
3586
|
+
y = parseFloat(arrCoord[1]);
|
|
3587
|
+
bboxCoords.push(new Point2D(x, y));
|
|
3588
|
+
}
|
|
3589
|
+
//use the upper left corner of the MBR containing geoCoords
|
|
3590
|
+
//to set the converter
|
|
3591
|
+
ptGeoUL = MultiPointHandler.getGeoUL(bboxCoords);
|
|
3592
|
+
left = ptGeoUL.getX();
|
|
3593
|
+
top = ptGeoUL.getY();
|
|
3594
|
+
let bbox2: string = MultiPointHandler.getBboxFromCoords(bboxCoords);
|
|
3595
|
+
scale = MultiPointHandler.getReasonableScale(bbox2, scale);
|
|
3596
|
+
ipc = new PointConverter(left, top, scale);
|
|
3597
|
+
let ptPixels: Point2D;
|
|
3598
|
+
let ptGeo: Point2D;
|
|
3599
|
+
let n: int = bboxCoords.length;
|
|
3600
|
+
//for (j = 0; j < bboxCoords.length; j++)
|
|
3601
|
+
for (j = 0; j < n; j++) {
|
|
3602
|
+
ptGeo = bboxCoords[j];
|
|
3603
|
+
ptPixels = ipc.GeoToPixels(ptGeo);
|
|
3604
|
+
x = ptPixels.getX();
|
|
3605
|
+
y = ptPixels.getY();
|
|
3606
|
+
if (x < 20) {
|
|
3607
|
+
x = 20;
|
|
3608
|
+
}
|
|
3609
|
+
if (y < 20) {
|
|
3610
|
+
y = 20;
|
|
3611
|
+
}
|
|
3612
|
+
ptPixels.setLocation(x, y);
|
|
3613
|
+
//end section
|
|
3614
|
+
bboxCoords[j] = ptPixels;
|
|
3615
|
+
}
|
|
3616
|
+
} else//rectangle
|
|
3617
|
+
{
|
|
3618
|
+
bounds = bbox.split(",");
|
|
3619
|
+
left = parseFloat(bounds[0]);
|
|
3620
|
+
right = parseFloat(bounds[2]);
|
|
3621
|
+
top = parseFloat(bounds[3]);
|
|
3622
|
+
bottom = parseFloat(bounds[1]);
|
|
3623
|
+
scale = MultiPointHandler.getReasonableScale(bbox, scale);
|
|
3624
|
+
ipc = new PointConverter(left, top, scale);
|
|
3625
|
+
}
|
|
3626
|
+
|
|
3627
|
+
let pt2d: Point2D;
|
|
3628
|
+
if (bboxCoords == null) {
|
|
3629
|
+
pt2d = new Point2D(left, top);
|
|
3630
|
+
temp = ipc.GeoToPixels(pt2d);
|
|
3631
|
+
|
|
3632
|
+
leftX = temp.getX() as int;
|
|
3633
|
+
topY = temp.getY() as int;
|
|
3634
|
+
|
|
3635
|
+
pt2d = new Point2D(right, bottom);
|
|
3636
|
+
temp = ipc.GeoToPixels(pt2d);
|
|
3637
|
+
|
|
3638
|
+
bottomY = temp.getY() as int;
|
|
3639
|
+
rightX = temp.getX() as int;
|
|
3640
|
+
|
|
3641
|
+
width = Math.abs(rightX - leftX) as int;
|
|
3642
|
+
height = Math.abs(bottomY - topY) as int;
|
|
3643
|
+
|
|
3644
|
+
rect = new Rectangle(leftX, topY, width, height);
|
|
3645
|
+
}
|
|
3646
|
+
} else {
|
|
3647
|
+
rect = null;
|
|
3648
|
+
}
|
|
3649
|
+
|
|
3650
|
+
if (ipc == null) {
|
|
3651
|
+
let ptCoordsUL: Point2D = MultiPointHandler.getGeoUL(geoCoords);
|
|
3652
|
+
ipc = new PointConverter(ptCoordsUL.getX(), ptCoordsUL.getY(), scale);
|
|
3653
|
+
}
|
|
3654
|
+
|
|
3655
|
+
let geoCoords2: Array<Point2D> = new Array<Point2D>();
|
|
3656
|
+
geoCoords2.push(new Point2D(left, top));
|
|
3657
|
+
geoCoords2.push(new Point2D(right, bottom));
|
|
3658
|
+
|
|
3659
|
+
// if (normalize) {
|
|
3660
|
+
// NormalizeGECoordsToGEExtents(0, 360, geoCoords2);
|
|
3661
|
+
// }
|
|
3662
|
+
|
|
3663
|
+
try {
|
|
3664
|
+
|
|
3665
|
+
//String fillColor = null;
|
|
3666
|
+
let mSymbol: MilStdSymbol = new MilStdSymbol(symbolCode, null, geoCoords, null);
|
|
3667
|
+
|
|
3668
|
+
if (format == WebRenderer.OUTPUT_FORMAT_GEOSVG) {
|
|
3669
|
+
// Use dash array and hatch pattern fill for SVG output
|
|
3670
|
+
symbolAttributes.set(MilStdAttributes.UseDashArray, 'true')
|
|
3671
|
+
symbolAttributes.set(MilStdAttributes.UsePatternFill, "true")
|
|
3672
|
+
}
|
|
3673
|
+
|
|
3674
|
+
if (symbolModifiers != null || symbolAttributes != null) {
|
|
3675
|
+
MultiPointHandler.populateModifiers(symbolModifiers, symbolAttributes, mSymbol);
|
|
3676
|
+
} else {
|
|
3677
|
+
mSymbol.setFillColor(null);
|
|
3678
|
+
}
|
|
3679
|
+
|
|
3680
|
+
let tg: TGLight = clsRenderer.createTGLightFromMilStdSymbolBasicShape(mSymbol, ipc, basicShapeType);
|
|
3681
|
+
let shapeInfos: Array<ShapeInfo> = [];
|
|
3682
|
+
let modifierShapeInfos: Array<ShapeInfo> = [];
|
|
3683
|
+
let clipArea: Point2D[] | Rectangle | Rectangle2D;
|
|
3684
|
+
if (bboxCoords == null) {
|
|
3685
|
+
clipArea = rect;
|
|
3686
|
+
} else {
|
|
3687
|
+
clipArea = bboxCoords;
|
|
3688
|
+
}
|
|
3689
|
+
if (clsRenderer.intersectsClipArea(tg, ipc, clipArea)) {
|
|
3690
|
+
clsRenderer.render_GE(tg, shapeInfos, modifierShapeInfos, ipc, clipArea);
|
|
3691
|
+
}
|
|
3692
|
+
mSymbol.setSymbolShapes(shapeInfos);
|
|
3693
|
+
mSymbol.setModifierShapes(modifierShapeInfos);
|
|
3694
|
+
mSymbol.set_WasClipped(tg.get_WasClipped());
|
|
3695
|
+
shapes = mSymbol.getSymbolShapes();
|
|
3696
|
+
modifiers = mSymbol.getModifierShapes();
|
|
3697
|
+
|
|
3698
|
+
if (format === WebRenderer.OUTPUT_FORMAT_JSON) {
|
|
3699
|
+
jsonOutput += ("{\"type\":\"symbol\",");
|
|
3700
|
+
jsonContent = MultiPointHandler.JSONize(shapes, modifiers, ipc, true, normalize);
|
|
3701
|
+
jsonOutput += (jsonContent);
|
|
3702
|
+
jsonOutput += ("}");
|
|
3703
|
+
} else if (format === WebRenderer.OUTPUT_FORMAT_KML) {
|
|
3704
|
+
var textColor = mSymbol.getTextColor();
|
|
3705
|
+
if(textColor==null)
|
|
3706
|
+
textColor=mSymbol.getLineColor();
|
|
3707
|
+
|
|
3708
|
+
jsonContent = MultiPointHandler.KMLize(id, name, description, symbolCode, shapes, modifiers, ipc, normalize, textColor);
|
|
3709
|
+
jsonOutput += jsonContent;
|
|
3710
|
+
} else if (format === WebRenderer.OUTPUT_FORMAT_GEOJSON) {
|
|
3711
|
+
/*
|
|
3712
|
+
jsonOutput += ("{\"type\":\"FeatureCollection\",\"features\":");
|
|
3713
|
+
jsonContent = GeoJSONize(shapes, modifiers, ipc, normalize, mSymbol.getTextColor(), mSymbol.getTextBackgroundColor());
|
|
3714
|
+
jsonOutput += (jsonContent);
|
|
3715
|
+
jsonOutput += (",\"properties\":{\"id\":\"");
|
|
3716
|
+
jsonOutput += (id);
|
|
3717
|
+
jsonOutput += ("\",\"name\":\"");
|
|
3718
|
+
jsonOutput += (name);
|
|
3719
|
+
jsonOutput += ("\",\"description\":\"");
|
|
3720
|
+
jsonOutput += (description);
|
|
3721
|
+
jsonOutput += ("\",\"symbolID\":\"");
|
|
3722
|
+
jsonOutput += (symbolCode);
|
|
3723
|
+
jsonOutput += ("\",\"wasClipped\":\"");
|
|
3724
|
+
jsonOutput += (mSymbol.get_WasClipped()).toString();
|
|
3725
|
+
jsonOutput += ("\"}}"); */
|
|
3726
|
+
|
|
3727
|
+
jsonOutput += ("{\"type\":\"FeatureCollection\",\"features\":");
|
|
3728
|
+
jsonContent = MultiPointHandler.GeoJSONize(shapes, modifiers, ipc, normalize, mSymbol.getTextColor(), mSymbol.getTextBackgroundColor());
|
|
3729
|
+
jsonOutput += (jsonContent);
|
|
3730
|
+
|
|
3731
|
+
//moving meta data properties to the last feature with no coords as feature collection doesn't allow properties
|
|
3732
|
+
jsonOutput = jsonOutput.slice(0, -1);
|
|
3733
|
+
jsonOutput += (",{\"type\": \"Feature\",\"geometry\": { \"type\": \"Polygon\",\"coordinates\": [ ]}");
|
|
3734
|
+
|
|
3735
|
+
jsonOutput += (",\"properties\":{\"id\":\"");
|
|
3736
|
+
jsonOutput += (id);
|
|
3737
|
+
jsonOutput += ("\",\"name\":\"");
|
|
3738
|
+
jsonOutput += (name);
|
|
3739
|
+
jsonOutput += ("\",\"description\":\"");
|
|
3740
|
+
jsonOutput += (description);
|
|
3741
|
+
jsonOutput += ("\",\"symbolID\":\"");
|
|
3742
|
+
jsonOutput += (symbolCode);
|
|
3743
|
+
jsonOutput += ("\",\"wasClipped\":\"");
|
|
3744
|
+
jsonOutput += (mSymbol.get_WasClipped()).toString();
|
|
3745
|
+
//jsonOutput += ("\"}}");
|
|
3746
|
+
|
|
3747
|
+
jsonOutput += ("\"}}]}");
|
|
3748
|
+
} else if (format === WebRenderer.OUTPUT_FORMAT_GEOSVG) {
|
|
3749
|
+
let textColor = mSymbol.getTextColor() ? mSymbol.getTextColor().toHexString(false) : "";
|
|
3750
|
+
let backgroundColor = mSymbol.getTextBackgroundColor() ? mSymbol.getTextBackgroundColor().toHexString(false) : "";
|
|
3751
|
+
//returns an svg with a geoTL and geoBR value to use to place the canvas on the map
|
|
3752
|
+
jsonOutput = MultiPointHandlerSVG.GeoSVGize(id, name, description, symbolCode, shapes, modifiers, ipc, normalize, textColor, backgroundColor, mSymbol.get_WasClipped());
|
|
3753
|
+
}
|
|
3754
|
+
} catch (exc) {
|
|
3755
|
+
if (exc instanceof Error) {
|
|
3756
|
+
let st: string = JavaRendererUtilities.getStackTrace(exc);
|
|
3757
|
+
jsonOutput = "";
|
|
3758
|
+
jsonOutput += ("{\"type\":\"error\",\"error\":\"There was an error creating the MilStdSymbol " + symbolCode + ": " + "- ");
|
|
3759
|
+
jsonOutput += (exc.message + " - ");
|
|
3760
|
+
jsonOutput += (st);
|
|
3761
|
+
jsonOutput += ("\"}");
|
|
3762
|
+
|
|
3763
|
+
ErrorLogger.LogException("MultiPointHandler", "RenderBasicSymbol", exc);
|
|
3764
|
+
} else {
|
|
3765
|
+
throw exc;
|
|
3766
|
+
}
|
|
3767
|
+
}
|
|
3768
|
+
|
|
3769
|
+
/*
|
|
3770
|
+
let debug: boolean = false;
|
|
3771
|
+
if (debug === true) {
|
|
3772
|
+
console.log("Symbol Code: " + symbolCode);
|
|
3773
|
+
console.log("Scale: " + scale);
|
|
3774
|
+
console.log("BBOX: " + bbox);
|
|
3775
|
+
if (controlPoints != null) {
|
|
3776
|
+
console.log("Geo Points: " + controlPoints);
|
|
3777
|
+
}
|
|
3778
|
+
if (tgl != null && tgl.get_Pixels() != null)//pixels != null
|
|
3779
|
+
{
|
|
3780
|
+
console.log("Pixel: " + tgl.get_Pixels().toString());
|
|
3781
|
+
}
|
|
3782
|
+
if (bbox != null) {
|
|
3783
|
+
console.log("geo bounds: " + bbox);
|
|
3784
|
+
}
|
|
3785
|
+
if (rect != null) {
|
|
3786
|
+
console.log("pixel bounds: " + rect.toString());
|
|
3787
|
+
}
|
|
3788
|
+
if (jsonOutput != null) {
|
|
3789
|
+
console.log(jsonOutput.toString());
|
|
3790
|
+
}
|
|
3791
|
+
}
|
|
3792
|
+
*/
|
|
3793
|
+
|
|
3794
|
+
ErrorLogger.LogMessage("MultiPointHandler", "RenderBasicShape()", "exit RenderBasicShape", LogLevel.FINER);
|
|
3795
|
+
return jsonOutput.toString();
|
|
3796
|
+
|
|
3797
|
+
}
|
|
3798
|
+
}
|