001/* 002 * A class to serve JavaRendererServer 003 */ 004package armyc2.c5isr.RenderMultipoints; 005 006import android.content.Context; 007 008import java.util.ArrayList; 009import java.util.Collections; 010import java.util.HashMap; 011import java.util.Map; 012 013import armyc2.c5isr.JavaLineArray.CELineArray; 014import armyc2.c5isr.JavaLineArray.DISMSupport; 015import armyc2.c5isr.JavaLineArray.POINT2; 016import armyc2.c5isr.JavaLineArray.Shape2; 017import armyc2.c5isr.JavaLineArray.TacticalLines; 018import armyc2.c5isr.JavaLineArray.lineutility; 019import armyc2.c5isr.JavaTacticalRenderer.Modifier2; 020import armyc2.c5isr.JavaTacticalRenderer.TGLight; 021import armyc2.c5isr.JavaTacticalRenderer.mdlGeodesic; 022import armyc2.c5isr.graphics2d.BasicStroke; 023import armyc2.c5isr.graphics2d.BufferedImage; 024import armyc2.c5isr.graphics2d.Font; 025import armyc2.c5isr.graphics2d.Graphics2D; 026import armyc2.c5isr.graphics2d.Point2D; 027import armyc2.c5isr.graphics2d.Rectangle; 028import armyc2.c5isr.graphics2d.Rectangle2D; 029import armyc2.c5isr.renderer.utilities.Color; 030import armyc2.c5isr.renderer.utilities.DistanceUnit; 031import armyc2.c5isr.renderer.utilities.DrawRules; 032import armyc2.c5isr.renderer.utilities.ErrorLogger; 033import armyc2.c5isr.renderer.utilities.IPointConversion; 034import armyc2.c5isr.renderer.utilities.MSInfo; 035import armyc2.c5isr.renderer.utilities.MSLookup; 036import armyc2.c5isr.renderer.utilities.MilStdSymbol; 037import armyc2.c5isr.renderer.utilities.Modifiers; 038import armyc2.c5isr.renderer.utilities.RendererException; 039import armyc2.c5isr.renderer.utilities.RendererSettings; 040import armyc2.c5isr.renderer.utilities.ShapeInfo; 041import armyc2.c5isr.renderer.utilities.SymbolID; 042import armyc2.c5isr.renderer.utilities.SymbolUtilities; 043 044/** 045 * Rendering class 046 * 047* 048 */ 049public final class clsRenderer { 050 051 private static final String _className = "clsRenderer"; 052 053 /** 054 * Set tg geo points from the client points 055 * 056 * @param milStd 057 * @param tg 058 */ 059 private static void setClientCoords(MilStdSymbol milStd, 060 TGLight tg) { 061 try { 062 ArrayList<POINT2> latLongs = new ArrayList(); 063 int j = 0; 064 ArrayList<Point2D> coords = milStd.getCoordinates(); 065 Point2D pt2d = null; 066 POINT2 pt2 = null; 067 int n = coords.size(); 068 //for (j = 0; j < coords.size(); j++) 069 for (j = 0; j < n; j++) { 070 pt2d = coords.get(j); 071 pt2 = clsUtility.Point2DToPOINT2(pt2d); 072 latLongs.add(pt2); 073 } 074 tg.set_LatLongs(latLongs); 075 } catch (Exception exc) { 076 ErrorLogger.LogException("clsRenderer", "setClientCoords", 077 new RendererException("Failed to set geo points or pixels for " + milStd.getSymbolID(), exc)); 078 } 079 } 080 081 private static ArrayList<Point2D> getClientCoords(TGLight tg) { 082 ArrayList<Point2D> coords = null; 083 try { 084 int j = 0; 085 Point2D pt2d = null; 086 POINT2 pt2 = null; 087 coords = new ArrayList(); 088 int n = tg.LatLongs.size(); 089 //for (j = 0; j < tg.LatLongs.size(); j++) 090 for (j = 0; j < n; j++) { 091 pt2 = tg.LatLongs.get(j); 092 pt2d = new Point2D.Double(pt2.x, pt2.y); 093 coords.add(pt2d); 094 } 095 } catch (Exception exc) { 096 ErrorLogger.LogException("clsRenderer", "getClientCoords", 097 new RendererException("Failed to set geo points or pixels for " + tg.get_SymbolId(), exc)); 098 } 099 return coords; 100 } 101 102 /** 103 * Create MilStdSymbol from tactical graphic 104 * 105 * @deprecated 106 * @param tg tactical graphic 107 * @param converter geographic to pixels to converter 108 * @return MilstdSymbol object 109 */ 110 public static MilStdSymbol createMilStdSymboFromTGLight(TGLight tg, IPointConversion converter) { 111 MilStdSymbol milStd = null; 112 try { 113 String symbolId = tg.get_SymbolId(); 114 int lineType = armyc2.c5isr.JavaTacticalRenderer.clsUtility.GetLinetypeFromString(symbolId); 115 String status = tg.get_Status(); 116 //build tg.Pixels 117 tg.Pixels = clsUtility.LatLongToPixels(tg.LatLongs, converter); 118 boolean isClosedArea = armyc2.c5isr.JavaTacticalRenderer.clsUtility.isClosedPolygon(lineType); 119 if (isClosedArea) { 120 armyc2.c5isr.JavaTacticalRenderer.clsUtility.ClosePolygon(tg.Pixels); 121 armyc2.c5isr.JavaTacticalRenderer.clsUtility.ClosePolygon(tg.LatLongs); 122 } 123 124 ArrayList<Point2D> coords = getClientCoords(tg); 125 tg.set_Font(new Font("Arial", Font.PLAIN, 12)); 126 Map<String,String> modifiers = new HashMap<>(); 127 modifiers.put(Modifiers.W_DTG_1, tg.get_DTG()); 128 modifiers.put(Modifiers.W1_DTG_2, tg.get_DTG1()); 129 modifiers.put(Modifiers.H_ADDITIONAL_INFO_1, tg.get_H()); 130 modifiers.put(Modifiers.H1_ADDITIONAL_INFO_2, tg.get_H1()); 131 modifiers.put(Modifiers.H2_ADDITIONAL_INFO_3, tg.get_H2()); 132 modifiers.put(Modifiers.T_UNIQUE_DESIGNATION_1, tg.get_Name()); 133 modifiers.put(Modifiers.T1_UNIQUE_DESIGNATION_2, tg.get_T1()); 134 modifiers.put(Modifiers.Y_LOCATION, tg.get_Location()); 135 modifiers.put(Modifiers.N_HOSTILE, tg.get_N()); 136 137 milStd = new MilStdSymbol(symbolId, "1", coords, modifiers); 138 milStd.setFillColor(tg.get_FillColor()); 139 milStd.setLineColor(tg.get_LineColor()); 140 milStd.setLineWidth(tg.get_LineThickness()); 141 milStd.setFillStyle(tg.get_TexturePaint()); 142 } catch (Exception exc) { 143 ErrorLogger.LogException("clsRenderer", "createMilStdSymboFromTGLight", 144 new RendererException("Failed to set geo points or pixels for " + tg.get_SymbolId(), exc)); 145 } 146 return milStd; 147 } 148 149 /** 150 * Build a tactical graphic object from the client MilStdSymbol 151 * 152 * @param milStd MilstdSymbol object 153 * @param converter geographic to pixels converter 154 * @return tactical graphic 155 */ 156 public static TGLight createTGLightFromMilStdSymbol(MilStdSymbol milStd, 157 IPointConversion converter) { 158 TGLight tg = new TGLight(); 159 try { 160 String symbolId = milStd.getSymbolID(); 161 tg.set_SymbolId(symbolId); 162 boolean useLineInterpolation = milStd.getUseLineInterpolation(); 163 tg.set_UseLineInterpolation(useLineInterpolation); 164 int lineType = armyc2.c5isr.JavaTacticalRenderer.clsUtility.GetLinetypeFromString(symbolId); 165 tg.set_LineType(lineType); 166 String status = tg.get_Status(); 167 if (status != null && status.equals("A")) { 168 tg.set_LineStyle(1); 169 } 170 tg.set_VisibleModifiers(true); 171 //set tg latlongs and pixels 172 setClientCoords(milStd, tg); 173 //build tg.Pixels 174 tg.Pixels = clsUtility.LatLongToPixels(tg.LatLongs, converter); 175 //tg.set_Font(new Font("Arial", Font.PLAIN, 12)); 176 RendererSettings r = RendererSettings.getInstance(); 177 int type = r.getMPLabelFontType(); 178 String name = r.getMPLabelFontName(); 179 int sz = r.getMPLabelFontSize(); 180 Font font = new Font(name, type, sz); 181 tg.set_Font(font); 182 tg.set_FillColor(milStd.getFillColor()); 183 tg.set_LineColor(milStd.getLineColor()); 184 tg.set_LineThickness(milStd.getLineWidth()); 185 tg.set_TexturePaint(milStd.getFillStyle()); 186 187 tg.set_IconSize(milStd.getUnitSize()); 188 tg.set_KeepUnitRatio(milStd.getKeepUnitRatio()); 189 190 tg.set_FontBackColor(Color.WHITE); 191 tg.set_TextColor(milStd.getTextColor()); 192 if (milStd.getModifier(Modifiers.W_DTG_1) != null) { 193 tg.set_DTG(milStd.getModifier(Modifiers.W_DTG_1)); 194 } 195 if (milStd.getModifier(Modifiers.W1_DTG_2) != null) { 196 tg.set_DTG1(milStd.getModifier(Modifiers.W1_DTG_2)); 197 } 198 if (milStd.getModifier(Modifiers.H_ADDITIONAL_INFO_1) != null) { 199 tg.set_H(milStd.getModifier(Modifiers.H_ADDITIONAL_INFO_1)); 200 } 201 if (milStd.getModifier(Modifiers.H1_ADDITIONAL_INFO_2) != null) { 202 tg.set_H1(milStd.getModifier(Modifiers.H1_ADDITIONAL_INFO_2)); 203 } 204 if (milStd.getModifier(Modifiers.H2_ADDITIONAL_INFO_3) != null) { 205 tg.set_H2(milStd.getModifier(Modifiers.H2_ADDITIONAL_INFO_3)); 206 } 207 if (milStd.getModifier(Modifiers.T_UNIQUE_DESIGNATION_1) != null) { 208 tg.set_Name(milStd.getModifier(Modifiers.T_UNIQUE_DESIGNATION_1)); 209 } 210 if (milStd.getModifier(Modifiers.T1_UNIQUE_DESIGNATION_2) != null) { 211 tg.set_T1(milStd.getModifier(Modifiers.T1_UNIQUE_DESIGNATION_2)); 212 } 213 if (milStd.getModifier(Modifiers.V_EQUIP_TYPE) != null) { 214 tg.set_V(milStd.getModifier(Modifiers.V_EQUIP_TYPE)); 215 } 216 if (milStd.getModifier(Modifiers.AS_COUNTRY) != null) { 217 tg.set_AS(milStd.getModifier(Modifiers.AS_COUNTRY)); 218 } 219 if (milStd.getModifier(Modifiers.AP_TARGET_NUMBER) != null) { 220 tg.set_AP(milStd.getModifier(Modifiers.AP_TARGET_NUMBER)); 221 } 222 if (milStd.getModifier(Modifiers.Y_LOCATION) != null) { 223 tg.set_Location(milStd.getModifier(Modifiers.Y_LOCATION)); 224 } 225 if (milStd.getModifier(Modifiers.N_HOSTILE) != null) { 226 tg.set_N(milStd.getModifier(Modifiers.N_HOSTILE)); 227 } 228 tg.set_UseDashArray(milStd.getUseDashArray()); 229 tg.set_UseHatchFill(milStd.getUseFillPattern()); 230 //tg.set_UsePatternFill(milStd.getUseFillPattern()); 231 tg.set_HideOptionalLabels(milStd.getHideOptionalLabels()); 232 boolean isClosedArea = armyc2.c5isr.JavaTacticalRenderer.clsUtility.isClosedPolygon(lineType); 233 234 if (lineType == TacticalLines.STRIKWARN) { 235 ArrayList<POINT2> poly1Pixels = new ArrayList<>(tg.Pixels.subList(0, tg.Pixels.size() / 2)); 236 ArrayList<POINT2> poly1LatLons = new ArrayList<>(tg.LatLongs.subList(0, tg.LatLongs.size() / 2)); 237 ArrayList<POINT2> poly2Pixels = new ArrayList<>(tg.Pixels.subList(tg.Pixels.size() / 2, tg.Pixels.size())); 238 ArrayList<POINT2> poly2LatLons = new ArrayList<>(tg.LatLongs.subList(tg.LatLongs.size() / 2, tg.LatLongs.size())); 239 240 armyc2.c5isr.JavaTacticalRenderer.clsUtility.ClosePolygon(poly1Pixels); 241 armyc2.c5isr.JavaTacticalRenderer.clsUtility.ClosePolygon(poly1LatLons); 242 tg.Pixels = poly1Pixels; 243 tg.LatLongs = poly1LatLons; 244 245 armyc2.c5isr.JavaTacticalRenderer.clsUtility.ClosePolygon(poly2Pixels); 246 armyc2.c5isr.JavaTacticalRenderer.clsUtility.ClosePolygon(poly2LatLons); 247 tg.Pixels.addAll(poly2Pixels); 248 tg.LatLongs.addAll(poly2LatLons); 249 } 250 else if (isClosedArea) { 251 armyc2.c5isr.JavaTacticalRenderer.clsUtility.ClosePolygon(tg.Pixels); 252 armyc2.c5isr.JavaTacticalRenderer.clsUtility.ClosePolygon(tg.LatLongs); 253 } 254 255 //implement meters to feet for altitude labels 256 String altitudeLabel = milStd.getAltitudeMode(); 257 if (altitudeLabel == null || altitudeLabel.isEmpty()) { 258 altitudeLabel = "AMSL"; 259 } 260 DistanceUnit altitudeUnit = milStd.getAltitudeUnit(); 261 if(altitudeUnit == null){ 262 altitudeUnit = DistanceUnit.FEET; 263 } 264 DistanceUnit distanceUnit = milStd.getDistanceUnit(); 265 if(distanceUnit == null){ 266 distanceUnit = DistanceUnit.METERS; 267 } 268 269 String strXAlt = ""; 270 //construct the H1 and H2 modifiers for sector from the mss AM, AN, and X arraylists 271 if (lineType == TacticalLines.RANGE_FAN_SECTOR) { 272 ArrayList<Double> AM = milStd.getModifiers_AM_AN_X(Modifiers.AM_DISTANCE); 273 ArrayList<Double> AN = milStd.getModifiers_AM_AN_X(Modifiers.AN_AZIMUTH); 274 ArrayList<Double> X = milStd.getModifiers_AM_AN_X(Modifiers.X_ALTITUDE_DEPTH); 275 if (AM != null) { 276 String strAM = ""; 277 for (int j = 0; j < AM.size(); j++) { 278 strAM += Double.toString(AM.get(j)); 279 if (j < AM.size() - 1) { 280 strAM += ","; 281 } 282 } 283 tg.set_AM(strAM); 284 } 285 if (AN != null) { 286 String strAN = ""; 287 for (int j = 0; j < AN.size(); j++) { 288 strAN += AN.get(j); 289 if (j < AN.size() - 1) { 290 strAN += ","; 291 } 292 } 293 tg.set_AN(strAN); 294 } 295 if (X != null) { 296 String strX = ""; 297 for (int j = 0; j < X.size(); j++) { 298 strXAlt = createAltitudeLabel(X.get(j), altitudeUnit, altitudeLabel); 299 strX += strXAlt; 300 301 if (j < X.size() - 1) { 302 strX += ","; 303 } 304 } 305 tg.set_X(strX); 306 } 307 if (AM != null && AN != null) { 308 int numSectors = AN.size() / 2; 309 double left, right, min = 0, max = 0; 310 //construct left,right,min,max from the arraylists 311 String strLeftRightMinMax = ""; 312 for (int j = 0; j < numSectors; j++) { 313 left = AN.get(2 * j); 314 right = AN.get(2 * j + 1); 315 if (j + 1 == AM.size()) { 316 break; 317 } 318 min = AM.get(j); 319 max = AM.get(j + 1); 320 strLeftRightMinMax += Double.toString(left) + "," + Double.toString(right) + "," + Double.toString(min) + "," + Double.toString(max); 321 if (j < numSectors - 1) { 322 strLeftRightMinMax += ","; 323 } 324 325 } 326 int len = strLeftRightMinMax.length(); 327 String c = strLeftRightMinMax.substring(len - 1, len); 328 if (c.equalsIgnoreCase(",")) { 329 strLeftRightMinMax = strLeftRightMinMax.substring(0, len - 1); 330 } 331 tg.set_LRMM(strLeftRightMinMax); 332 } 333 } else if (lineType == TacticalLines.RADAR_SEARCH) { 334 ArrayList<Double> AM = milStd.getModifiers_AM_AN_X(Modifiers.AM_DISTANCE); 335 ArrayList<Double> AN = milStd.getModifiers_AM_AN_X(Modifiers.AN_AZIMUTH); 336 if (AM != null) { 337 String strAM = ""; 338 for (int j = 0; j < AM.size() && j < 2; j++) { 339 strAM += Double.toString(AM.get(j)); 340 if (j < AM.size() - 1) { 341 strAM += ","; 342 } 343 } 344 tg.set_AM(strAM); 345 } 346 if (AN != null) { 347 String strAN = ""; 348 for (int j = 0; j < AN.size() && j < 2; j++) { 349 strAN += AN.get(j); 350 if (j < AN.size() - 1) { 351 strAN += ","; 352 } 353 } 354 tg.set_AN(strAN); 355 } 356 if (AM != null && AN != null) { 357 double left, right, min = 0, max = 0; 358 //construct left,right,min,max from the arraylists 359 String strLeftRightMinMax = ""; 360 left = AN.get(0); 361 right = AN.get(1); 362 min = AM.get(0); 363 max = AM.get(1); 364 strLeftRightMinMax += Double.toString(left) + "," + Double.toString(right) + "," + Double.toString(min) + "," + Double.toString(max); 365 tg.set_LRMM(strLeftRightMinMax); 366 } 367 } 368 int j = 0; 369 if (lineType == TacticalLines.LAUNCH_AREA || lineType == TacticalLines.DEFENDED_AREA_CIRCULAR || lineType == TacticalLines.SHIP_AOI_CIRCULAR) //geo ellipse 370 { 371 ArrayList<Double> AM = milStd.getModifiers_AM_AN_X(Modifiers.AM_DISTANCE); 372 ArrayList<Double> AN = milStd.getModifiers_AM_AN_X(Modifiers.AN_AZIMUTH); 373 if (AM != null && AM.size() > 1) { 374 String strAM = AM.get(0).toString(); // major axis 375 tg.set_AM(strAM); 376 String strAM1 = AM.get(1).toString(); // minor axis 377 tg.set_AM1(strAM1); 378 } 379 if (AN != null && AN.size() > 0) { 380 String strAN = AN.get(0).toString(); // rotation 381 tg.set_AN(strAN); 382 } 383 } 384 switch (lineType) { 385 case TacticalLines.ROZ: 386 case TacticalLines.AARROZ: 387 case TacticalLines.UAROZ: 388 case TacticalLines.WEZ: 389 case TacticalLines.FEZ: 390 case TacticalLines.JEZ: 391 case TacticalLines.FAADZ: 392 case TacticalLines.HIDACZ: 393 case TacticalLines.MEZ: 394 case TacticalLines.LOMEZ: 395 case TacticalLines.HIMEZ: 396 case TacticalLines.ACA: 397 case TacticalLines.ACA_RECTANGULAR: 398 case TacticalLines.ACA_CIRCULAR: 399 ArrayList<Double> X = milStd.getModifiers_AM_AN_X(Modifiers.X_ALTITUDE_DEPTH); 400 if (X != null && X.size() > 0) { 401 strXAlt = createAltitudeLabel(X.get(0), altitudeUnit, altitudeLabel); 402 tg.set_X(strXAlt); 403 } 404 if (X != null && X.size() > 1) { 405 strXAlt = createAltitudeLabel(X.get(1), altitudeUnit, altitudeLabel); 406 tg.set_X1(strXAlt); 407 } 408 break; 409 case TacticalLines.SC: 410 case TacticalLines.MRR: 411 case TacticalLines.SL: 412 case TacticalLines.TC: 413 case TacticalLines.LLTR: 414 case TacticalLines.AC: 415 case TacticalLines.SAAFR: 416 POINT2 pt = tg.LatLongs.get(0); 417 Point2D pt2d0 = new Point2D.Double(pt.x, pt.y); 418 Point2D pt2d0Pixels = converter.GeoToPixels(pt2d0); 419 POINT2 pt0Pixels = new POINT2(pt2d0Pixels.getX(), pt2d0Pixels.getY()); 420 421 //get some point 10000 meters away from pt 422 //10000 should work for any scale 423 double dist = 10000; 424 POINT2 pt2 = mdlGeodesic.geodesic_coordinate(pt, dist, 0); 425 Point2D pt2d1 = new Point2D.Double(pt2.x, pt2.y); 426 Point2D pt2d1Pixels = converter.GeoToPixels(pt2d1); 427 POINT2 pt1Pixels = new POINT2(pt2d1Pixels.getX(), pt2d1Pixels.getY()); 428 //calculate pixels per meter 429 double distPixels = lineutility.CalcDistanceDouble(pt0Pixels, pt1Pixels); 430 double pixelsPerMeter = distPixels / dist; 431 432 ArrayList<Double> AM = milStd.getModifiers_AM_AN_X(Modifiers.AM_DISTANCE); 433 if (AM != null) { 434 String strAM = ""; 435 for (j = 0; j < AM.size(); j++) { 436 strAM += AM.get(j).toString(); 437 if (j < AM.size() - 1) { 438 strAM += ","; 439 } 440 } 441 tg.set_AM(strAM); 442 } 443 String[] strRadii = null; 444 //get the widest value 445 //the current requirement is to use the greatest width as the default width 446 double maxWidth = 0, 447 temp = 0; 448 double maxWidthMeters = 0; 449 if (tg.get_AM() != null && tg.get_AM().isEmpty() == false) { 450 strRadii = tg.get_AM().split(","); 451 if (strRadii.length > 0) { 452 for (j = 0; j < strRadii.length; j++) { 453 if (!Double.isNaN(Double.parseDouble(strRadii[j]))) { 454 temp = Double.parseDouble(strRadii[j]); 455 if (temp > maxWidth) { 456 maxWidth = temp; 457 } 458 } 459 } 460 maxWidthMeters = maxWidth; 461 maxWidth *= pixelsPerMeter / 2; 462 463 for (j = 0; j < tg.Pixels.size(); j++) { 464 if (strRadii.length > j) { 465 if (!Double.isNaN(Double.parseDouble(strRadii[j]))) { 466 double pixels = Double.parseDouble(strRadii[j]) * pixelsPerMeter / 2; 467 tg.Pixels.get(j).style = (int) pixels; 468 tg.LatLongs.get(j).style = (int) pixels; 469 } else { 470 tg.Pixels.get(j).style = (int) maxWidth; 471 tg.LatLongs.get(j).style = (int) maxWidth; 472 } 473 } else { 474 tg.Pixels.get(j).style = (int) maxWidth; 475 tg.LatLongs.get(j).style = (int) maxWidth; 476 } 477 } 478 } 479 } 480 481 maxWidthMeters *= distanceUnit.conversionFactor; 482 maxWidthMeters *= 10.0; 483 maxWidthMeters = Math.round(maxWidthMeters); 484 int tempWidth = (int) maxWidthMeters; 485 maxWidthMeters = tempWidth / 10.0; 486 487 tg.set_AM(Double.toString(maxWidthMeters) + " " + distanceUnit.label); 488 //use X, X1 to set tg.H, tg.H1 489 X = milStd.getModifiers_AM_AN_X(Modifiers.X_ALTITUDE_DEPTH); 490 if (X != null && X.size() > 0) { 491 strXAlt = createAltitudeLabel(X.get(0), altitudeUnit, altitudeLabel); 492 tg.set_X(strXAlt); 493 } 494 if (X != null && X.size() > 1) { 495 strXAlt = createAltitudeLabel(X.get(1), altitudeUnit, altitudeLabel); 496 tg.set_X1(strXAlt); 497 } 498 break; 499 default: 500 break; 501 } 502 //circular range fans 503 if (lineType == TacticalLines.RANGE_FAN) { 504 ArrayList<Double> AM = milStd.getModifiers_AM_AN_X(Modifiers.AM_DISTANCE); 505 ArrayList<Double> X = milStd.getModifiers_AM_AN_X(Modifiers.X_ALTITUDE_DEPTH); 506 String strAM = ""; 507 String strX = ""; 508 if (AM != null) { 509 // Range fan circular has a maximum of 3 circles 510 for (j = 0; j < AM.size() && j < 3; j++) { 511 strAM += Double.toString(AM.get(j)); 512 if (j < AM.size() - 1) { 513 strAM += ","; 514 } 515 516 if (X != null && j < X.size()) { 517 strXAlt = createAltitudeLabel(X.get(j), altitudeUnit, altitudeLabel); 518 strX += strXAlt; 519 if (j < X.size() - 1) { 520 strX += ","; 521 } 522 } 523 } 524 } 525 tg.set_AM(strAM); 526 tg.set_X(strX); 527 } 528 switch (lineType) { 529 case TacticalLines.PAA_RECTANGULAR: 530 case TacticalLines.RECTANGULAR_TARGET: 531 case TacticalLines.FSA_RECTANGULAR: 532 case TacticalLines.SHIP_AOI_RECTANGULAR: 533 case TacticalLines.DEFENDED_AREA_RECTANGULAR: 534 case TacticalLines.FFA_RECTANGULAR: 535 case TacticalLines.ACA_RECTANGULAR: 536 case TacticalLines.NFA_RECTANGULAR: 537 case TacticalLines.RFA_RECTANGULAR: 538 case TacticalLines.ATI_RECTANGULAR: 539 case TacticalLines.CFFZ_RECTANGULAR: 540 case TacticalLines.SENSOR_RECTANGULAR: 541 case TacticalLines.CENSOR_RECTANGULAR: 542 case TacticalLines.DA_RECTANGULAR: 543 case TacticalLines.CFZ_RECTANGULAR: 544 case TacticalLines.ZOR_RECTANGULAR: 545 case TacticalLines.TBA_RECTANGULAR: 546 case TacticalLines.TVAR_RECTANGULAR: 547 case TacticalLines.CIRCULAR: 548 case TacticalLines.BDZ: 549 case TacticalLines.FSA_CIRCULAR: 550 case TacticalLines.NOTACK: 551 case TacticalLines.ACA_CIRCULAR: 552 case TacticalLines.FFA_CIRCULAR: 553 case TacticalLines.NFA_CIRCULAR: 554 case TacticalLines.RFA_CIRCULAR: 555 case TacticalLines.PAA_CIRCULAR: 556 case TacticalLines.ATI_CIRCULAR: 557 case TacticalLines.CFFZ_CIRCULAR: 558 case TacticalLines.SENSOR_CIRCULAR: 559 case TacticalLines.CENSOR_CIRCULAR: 560 case TacticalLines.DA_CIRCULAR: 561 case TacticalLines.CFZ_CIRCULAR: 562 case TacticalLines.ZOR_CIRCULAR: 563 case TacticalLines.TBA_CIRCULAR: 564 case TacticalLines.TVAR_CIRCULAR: 565 case TacticalLines.KILLBOXBLUE_CIRCULAR: 566 case TacticalLines.KILLBOXPURPLE_CIRCULAR: 567 case TacticalLines.KILLBOXBLUE_RECTANGULAR: 568 case TacticalLines.KILLBOXPURPLE_RECTANGULAR: 569 ArrayList<Double> AM = milStd.getModifiers_AM_AN_X(Modifiers.AM_DISTANCE); 570 if (AM != null && AM.size() > 0) { 571 String strAM = Double.toString(AM.get(0)); 572 //set width for rectangles or radius for circles 573 tg.set_AM(strAM); 574 } 575 break; 576 default: 577 break; 578 } 579 if (lineType == TacticalLines.RECTANGULAR || lineType == TacticalLines.CUED_ACQUISITION) { 580 ArrayList<Double> AM = milStd.getModifiers_AM_AN_X(Modifiers.AM_DISTANCE); 581 ArrayList<Double> AN = milStd.getModifiers_AM_AN_X(Modifiers.AN_AZIMUTH); 582 if (AN == null) { 583 AN = new ArrayList<>(); 584 } 585 if (AN.isEmpty()) { 586 AN.add(0d); 587 } 588 589 if (AM != null && AM.size() > 1) { 590 String strAM = Double.toString(AM.get(0)); //width 591 String strAM1 = Double.toString(AM.get(1)); //length 592 //set width and length in meters for rectangular target 593 tg.set_AM(strAM); 594 tg.set_AM1(strAM1); 595 //set attitude in degrees 596 String strAN = Double.toString(AN.get(0)); 597 tg.set_AN(strAN); 598 } 599 /* 600 if(AM.size()>2) 601 { 602 String strH1 = Double.toString(AM.get(2)); //buffer size 603 tg.set_H1(strH1); 604 } 605 */ 606 } 607 } catch (Exception exc) { 608 ErrorLogger.LogException("clsRenderer", "createTGLightfromMilStdSymbol", 609 new RendererException("Failed to build multipoint TG for " + milStd.getSymbolID(), exc)); 610 } 611 return tg; 612 } 613 614 private static String createAltitudeLabel(double distance, DistanceUnit altitudeUnit, String altitudeLabel){ 615 double conversionFactor; 616 617 // if using "FL" (Flight Level) for altitudeLabel, override conversion factor to avoid potential user error with altitudeUnit 618 if (altitudeLabel.equals("FL")) { 619 conversionFactor = DistanceUnit.FLIGHT_LEVEL.conversionFactor; 620 } else { 621 conversionFactor = altitudeUnit.conversionFactor; 622 } 623 624 // Truncate the result 625 double result = distance * conversionFactor; 626 result *= 10.0; 627 result = Math.round(result); 628 int tempResult = (int) result; 629 int truncatedResult = tempResult / 10; 630 // MIL-STD-2525D says altitude/depth must be an integer 631 632 // Simplifies labels of "0 units AGL" to "GL" (Ground Level) and "0 units AMSL/BMSL" to "MSL" (Mean Sea Level) 633 // as permitted by MIL-STD-2525D 5.3.7.5.1. 634 // Also works for "0 units GL" and "0 units MSL", which are improperly labeled but can be understood to mean the same thing. 635 if (truncatedResult == 0) { 636 if (altitudeLabel.equals("AGL") || altitudeLabel.equals("GL")) { 637 return "GL"; 638 } 639 if (altitudeLabel.equals("AMSL") || altitudeLabel.equals("BMSL") || altitudeLabel.equals("MSL")) { 640 return "MSL"; 641 } 642 } 643 644 // Flight level is a special altitude displayed as "FL ###" where ### are 3 digits representing hundreds of feet. 645 if (altitudeLabel.equals("FL")) { 646 return "FL " + String.format("%03d", truncatedResult); 647 } 648 649 return truncatedResult + " " + altitudeUnit.label + " " + altitudeLabel; 650 } 651 652 /** 653 * @deprecated @param milStd 654 * @param converter 655 * @param computeChannelPt 656 * @return 657 */ 658 public static TGLight createTGLightFromMilStdSymbol(MilStdSymbol milStd, 659 IPointConversion converter, Boolean computeChannelPt) { 660 TGLight tg = new TGLight(); 661 try { 662 String symbolId = milStd.getSymbolID(); 663 tg.set_SymbolId(symbolId); 664 String status = tg.get_Status(); 665 if (status != null && status.equals("A")) { 666 //lineStyle=GraphicProperties.LINE_TYPE_DASHED; 667 tg.set_LineStyle(1); 668 } 669 tg.set_VisibleModifiers(true); 670 //set tg latlongs and pixels 671 setClientCoords(milStd, tg); 672 //build tg.Pixels 673 tg.Pixels = clsUtility.LatLongToPixels(tg.LatLongs, converter); 674 tg.set_Font(new Font("Arial", Font.PLAIN, 12)); 675 tg.set_FillColor(milStd.getFillColor()); 676 tg.set_LineColor(milStd.getLineColor()); 677 tg.set_LineThickness(milStd.getLineWidth()); 678 tg.set_TexturePaint(milStd.getFillStyle()); 679 tg.set_FontBackColor(Color.WHITE); 680 tg.set_TextColor(milStd.getTextColor()); 681 682// tg.set_DTG(milStd.getModifier(Modifiers.W_DTG_1)); 683// tg.set_DTG1(milStd.getModifier(Modifiers.W1_DTG_2)); 684// tg.set_H(milStd.getModifier(Modifiers.H_ADDITIONAL_INFO_1)); 685// tg.set_H1(milStd.getModifier(Modifiers.H1_ADDITIONAL_INFO_2)); 686// tg.set_H2(milStd.getModifier(Modifiers.H2_ADDITIONAL_INFO_3)); 687// tg.set_Name(milStd.getModifier(Modifiers.T_UNIQUE_DESIGNATION_1)); 688// tg.set_T1(milStd.getModifier(Modifiers.T1_UNIQUE_DESIGNATION_2)); 689// tg.set_Location(milStd.getModifier(Modifiers.Y_LOCATION)); 690// tg.set_N(Modifiers.N_HOSTILE); 691 if (milStd.getModifier(Modifiers.W_DTG_1) != null) { 692 tg.set_DTG(milStd.getModifier(Modifiers.W_DTG_1)); 693 } 694 if (milStd.getModifier(Modifiers.W1_DTG_2) != null) { 695 tg.set_DTG1(milStd.getModifier(Modifiers.W1_DTG_2)); 696 } 697 if (milStd.getModifier(Modifiers.H_ADDITIONAL_INFO_1) != null) { 698 tg.set_H(milStd.getModifier(Modifiers.H_ADDITIONAL_INFO_1)); 699 } 700 if (milStd.getModifier(Modifiers.H1_ADDITIONAL_INFO_2) != null) { 701 tg.set_H1(milStd.getModifier(Modifiers.H1_ADDITIONAL_INFO_2)); 702 } 703 if (milStd.getModifier(Modifiers.H2_ADDITIONAL_INFO_3) != null) { 704 tg.set_H2(milStd.getModifier(Modifiers.H2_ADDITIONAL_INFO_3)); 705 } 706 if (milStd.getModifier(Modifiers.T_UNIQUE_DESIGNATION_1) != null) { 707 tg.set_Name(milStd.getModifier(Modifiers.T_UNIQUE_DESIGNATION_1)); 708 } 709 if (milStd.getModifier(Modifiers.T1_UNIQUE_DESIGNATION_2) != null) { 710 tg.set_T1(milStd.getModifier(Modifiers.T1_UNIQUE_DESIGNATION_2)); 711 } 712 if (milStd.getModifier(Modifiers.V_EQUIP_TYPE) != null) { 713 tg.set_V(milStd.getModifier(Modifiers.V_EQUIP_TYPE)); 714 } 715 if (milStd.getModifier(Modifiers.AS_COUNTRY) != null) { 716 tg.set_AS(milStd.getModifier(Modifiers.AS_COUNTRY)); 717 } 718 if (milStd.getModifier(Modifiers.AP_TARGET_NUMBER) != null) { 719 tg.set_AP(milStd.getModifier(Modifiers.AP_TARGET_NUMBER)); 720 } 721 if (milStd.getModifier(Modifiers.Y_LOCATION) != null) { 722 tg.set_Location(milStd.getModifier(Modifiers.Y_LOCATION)); 723 } 724 if (milStd.getModifier(Modifiers.N_HOSTILE) != null) { 725 tg.set_N(milStd.getModifier(Modifiers.N_HOSTILE)); 726 } 727 728 //int lineType=CELineArray.CGetLinetypeFromString(tg.get_SymbolId()); 729 int lineType = armyc2.c5isr.JavaTacticalRenderer.clsUtility.GetLinetypeFromString(symbolId); 730 boolean isClosedArea = armyc2.c5isr.JavaTacticalRenderer.clsUtility.isClosedPolygon(lineType); 731 732 if (isClosedArea) { 733 armyc2.c5isr.JavaTacticalRenderer.clsUtility.ClosePolygon(tg.Pixels); 734 armyc2.c5isr.JavaTacticalRenderer.clsUtility.ClosePolygon(tg.LatLongs); 735 } 736 737 //these channels need a channel point added 738 if (computeChannelPt) { 739 switch (lineType) { 740 case TacticalLines.CATK: 741 case TacticalLines.CATKBYFIRE: 742 case TacticalLines.AAAAA: 743 case TacticalLines.AIRAOA: 744 case TacticalLines.MAIN: 745 case TacticalLines.SPT: 746 POINT2 ptPixels = armyc2.c5isr.JavaTacticalRenderer.clsUtility.ComputeLastPoint(tg.Pixels); 747 tg.Pixels.add(ptPixels); 748 //Point pt = clsUtility.POINT2ToPoint(ptPixels); 749 Point2D pt = new Point2D.Double(ptPixels.x, ptPixels.y); 750 //in case it needs the corresponding geo point 751 Point2D ptGeo2d = converter.PixelsToGeo(pt); 752 POINT2 ptGeo = clsUtility.Point2DToPOINT2(ptGeo2d); 753 tg.LatLongs.add(ptGeo); 754 //} 755 break; 756 default: 757 break; 758 } 759 } 760 } catch (Exception exc) { 761 ErrorLogger.LogException("clsRenderer", "createTGLightfromMilStdSymbol", 762 new RendererException("Failed to build multipoint TG for " + milStd.getSymbolID(), exc)); 763 } 764 return tg; 765 } 766 767 private static void Shape2ToShapeInfo(ArrayList<ShapeInfo> shapeInfos, ArrayList<Shape2> shapes) { 768 try { 769 int j = 0; 770 Shape2 shape = null; 771 if (shapes == null || shapeInfos == null || shapes.size() == 0) { 772 return; 773 } 774 775 for (j = 0; j < shapes.size(); j++) { 776 shape = shapes.get(j); 777 shapeInfos.add((ShapeInfo) shape); 778 } 779 } catch (Exception exc) { 780 ErrorLogger.LogException("clsRenderer", "Shape2ToShapeInfo", 781 new RendererException("Failed to build ShapeInfo ArrayList", exc)); 782 } 783 } 784 785 /** 786 * Added function to handle when coords or display area spans IDL but not 787 * both, it prevents the symbol from rendering if the bounding rectangles 788 * don't intersect. 789 * 790 * @param tg 791 * @param converter 792 * @param clipArea 793 * @return 794 */ 795 public static boolean intersectsClipArea(TGLight tg, IPointConversion converter, Object clipArea) 796 { 797 boolean result=false; 798 try 799 { 800 if (clipArea==null || tg.LatLongs.size() < 2) 801 return true; 802 Rectangle2D clipBounds = null; 803 ArrayList<Point2D> clipPoints = null; 804 805// if (clipArea != null) { 806// if (clipArea.getClass().isAssignableFrom(Rectangle2D.Double.class)) { 807// clipBounds = (Rectangle2D.Double) clipArea; 808// } else if (clipArea.getClass().isAssignableFrom(Rectangle.class)) { 809// clipBounds = (Rectangle2D) clipArea; 810// } else if (clipArea.getClass().isAssignableFrom(ArrayList.class)) { 811// clipPoints = (ArrayList<Point2D>) clipArea; 812// } 813// } 814 if (clipArea != null) { 815 if (clipArea.getClass().isAssignableFrom(Rectangle2D.Double.class)) { 816 clipBounds = (Rectangle2D.Double) clipArea; 817 } else if (clipArea.getClass().isAssignableFrom(Rectangle.class)) { 818 Rectangle rectx = (Rectangle) clipArea; 819 clipBounds = new Rectangle2D.Double(rectx.x, rectx.y, rectx.width, rectx.height); 820 } else if (clipArea.getClass().isAssignableFrom(ArrayList.class)) { 821 clipPoints = (ArrayList<Point2D>) clipArea; 822 //double x0=clipPoints.get(0).getX(),y0=clipPoints.get(0).getY(); 823 //double w=clipPoints.get(1).getX()-x0,h=clipPoints.get(3).getY()-y0; 824 //clipBounds = new Rectangle2D.Double(x0, y0, w, h); 825 clipBounds=clsUtility.getMBR(clipPoints); 826 } 827 } 828 //assumes we are using clipBounds 829 int j = 0; 830 double x = clipBounds.getMinX(); 831 double y = clipBounds.getMinY(); 832 double width = clipBounds.getWidth(); 833 double height = clipBounds.getHeight(); 834 POINT2 tl = new POINT2(x, y); 835 POINT2 br = new POINT2(x + width, y + height); 836 tl = clsUtility.PointPixelsToLatLong(tl, converter); 837 br = clsUtility.PointPixelsToLatLong(br, converter); 838 //the latitude range 839 //boolean ptInside = false, ptAbove = false, ptBelow = false; 840 double coordsLeft = tg.LatLongs.get(0).x; 841 double coordsRight = coordsLeft; 842 double coordsTop=tg.LatLongs.get(0).y; 843 double coordsBottom=coordsTop; 844 boolean intersects=false; 845 double minx=tg.LatLongs.get(0).x,maxx=minx,maxNegX=0; 846 for (j = 0; j < tg.LatLongs.size(); j++) 847 { 848 POINT2 pt=tg.LatLongs.get(j); 849 if (pt.x < minx) 850 minx = pt.x; 851 if (pt.x > maxx) 852 maxx = pt.x; 853 if(maxNegX==0 && pt.x<0) 854 maxNegX=pt.x; 855 if(maxNegX<0 && pt.x<0 && pt.x>maxNegX) 856 maxNegX=pt.x; 857 if (pt.y < coordsBottom) 858 coordsBottom = pt.y; 859 if (pt.y > coordsTop) 860 coordsTop = pt.y; 861 } 862 boolean coordSpanIDL = false; 863 if(maxx==180 || minx==-180) 864 coordSpanIDL=true; 865 if(maxx-minx>=180) 866 { 867 coordSpanIDL=true; 868 coordsLeft=maxx; 869 coordsRight=maxNegX; 870 }else 871 { 872 coordsLeft=minx; 873 coordsRight=maxx; 874 } 875 //if(canClipPoints) 876 //{ 877 if(br.y<=coordsBottom && coordsBottom <= tl.y) 878 intersects=true; 879 else if(coordsBottom<=br.y && br.y <=coordsTop) 880 intersects=true; 881 else 882 return false; 883 //} 884 //if it gets this far then the latitude ranges intersect 885 //re-initialize intersects for the longitude ranges 886 intersects=false; 887 //the longitude range 888 //the min and max coords longitude 889 boolean boxSpanIDL = false; 890 //boolean coordSpanIDL = false; 891 if(tl.x==180 || tl.x==-180 || br.x==180 || br.x==-180) 892 boxSpanIDL=true; 893 else if (Math.abs(br.x - tl.x) > 180) 894 boxSpanIDL = true; 895 896// if (coordsRight - coordsLeft > 180) 897// { 898// double temp = coordsLeft; 899// coordsLeft = coordsRight; 900// coordsRight = temp; 901// coordSpanIDL=true; 902// } 903 //boolean intersects=false; 904 if(coordSpanIDL && boxSpanIDL) 905 intersects=true; 906 else if(!coordSpanIDL && !boxSpanIDL) //was && canclipPoints 907 { 908 if(coordsLeft<=tl.x && tl.x<=coordsRight) 909 intersects=true; 910 if(coordsLeft<=br.x && br.x<=coordsRight) 911 intersects=true; 912 if(tl.x<=coordsLeft && coordsLeft<=br.x) 913 intersects=true; 914 if(tl.x<=coordsRight && coordsRight<=br.x) 915 intersects=true; 916 } 917 else if(!coordSpanIDL && boxSpanIDL) //box spans IDL and coords do not 918 { 919 if(tl.x<coordsRight && coordsRight<180) 920 intersects=true; 921 if(-180<coordsLeft && coordsLeft<br.x) 922 intersects=true; 923 } 924 else if(coordSpanIDL && !boxSpanIDL) //coords span IDL and box does not 925 { 926 if(coordsLeft<br.x && br.x<180) 927 intersects=true; 928 if(-180<tl.x && tl.x<coordsRight) 929 intersects=true; 930 } 931 return intersects; 932 933 } 934 catch (Exception exc) { 935 ErrorLogger.LogException("clsRenderer", "intersectsClipArea", 936 new RendererException("Failed inside intersectsClipArea", exc)); 937 } 938 return result; 939 } 940 941 /** 942 * Adds Feint, decoy, or dummy indicator to shapes. Does not check if tactical graphic should have indicator 943 */ 944 private static void addFDI(TGLight tg, ArrayList<Shape2> shapes) { 945 try { 946 MSInfo msi = MSLookup.getInstance().getMSLInfo(tg.get_SymbolId()); 947 final int drawRule = msi != null ? msi.getDrawRule() : -1; 948 final int lineType = tg.get_LineType(); 949 950 if (lineType == TacticalLines.MAIN) { 951 // Only Axis of Advance with arrowhead in a different location 952 ArrayList<POINT2> points = shapes.get(1).getPoints(); 953 POINT2 ptA = new POINT2(points.get(points.size() - 3)); 954 POINT2 ptB = new POINT2(points.get(points.size() - 8)); 955 POINT2 ptC = new POINT2(points.get(points.size() - 7)); 956 shapes.add(DISMSupport.getFDIShape(tg, ptA, ptB, ptC)); 957 } else if (drawRule == DrawRules.AXIS1 || drawRule == DrawRules.AXIS2) { 958 // Axis of Advance symbols 959 ArrayList<POINT2> points = shapes.get(0).getPoints(); 960 POINT2 ptA = new POINT2(points.get(points.size() / 2 - 1)); 961 POINT2 ptB = new POINT2(points.get(points.size() / 2)); 962 POINT2 ptC = new POINT2(points.get(points.size() / 2 + 1)); 963 shapes.add(DISMSupport.getFDIShape(tg, ptA, ptB, ptC)); 964 } 965 // Direction of attack symbols 966 else if (lineType == TacticalLines.DIRATKAIR) { 967 ArrayList<POINT2> points = shapes.get(2).getPoints(); 968 POINT2 ptA = new POINT2(points.get(0)); 969 POINT2 ptB = new POINT2(points.get(1)); 970 POINT2 ptC = new POINT2(points.get(2)); 971 shapes.add(DISMSupport.getFDIShape(tg, ptA, ptB, ptC)); 972 } else if (lineType == TacticalLines.DIRATKGND) { 973 ArrayList<POINT2> points = shapes.get(1).getPoints(); 974 POINT2 ptA = new POINT2(points.get(7)); 975 POINT2 ptB = new POINT2(points.get(4)); 976 POINT2 ptC = new POINT2(points.get(9)); 977 shapes.add(DISMSupport.getFDIShape(tg, ptA, ptB, ptC)); 978 } else if (lineType == TacticalLines.DIRATKSPT) { 979 ArrayList<POINT2> points = shapes.get(1).getPoints(); 980 POINT2 ptA = new POINT2(points.get(0)); 981 POINT2 ptB = new POINT2(points.get(1)); 982 POINT2 ptC = new POINT2(points.get(2)); 983 shapes.add(DISMSupport.getFDIShape(tg, ptA, ptB, ptC)); 984 } else { 985 // Shape has no arrow. Put on top of shape 986 POINT2 firstPoint = shapes.get(0).getPoints().get(0); 987 POINT2 ptUl = new POINT2(firstPoint); 988 POINT2 ptUr = new POINT2(firstPoint); 989 POINT2 ptLr = new POINT2(firstPoint); 990 POINT2 ptLl = new POINT2(firstPoint); 991 clsUtility.GetMBR(shapes, ptUl, ptUr, ptLr, ptLl); 992 shapes.add(DISMSupport.getFDIShape(tg, ptUl, ptUr)); 993 } 994 } catch (Exception exc) { 995 ErrorLogger.LogException(_className, "addFDI", new RendererException("failed inside addFDI", exc)); 996 } 997 } 998 999 /** 1000 * @param mss 1001 * @param converter 1002 * @param clipArea 1003 * @param context 1004 * @deprecated context not used 1005 */ 1006 public static void renderWithPolylines(MilStdSymbol mss, 1007 IPointConversion converter, 1008 Object clipArea, 1009 Context context) { 1010 try { 1011 TGLight tg = clsRenderer.createTGLightFromMilStdSymbol(mss, converter); 1012 ArrayList<ShapeInfo> shapeInfos = new ArrayList(); 1013 ArrayList<ShapeInfo> modifierShapeInfos = new ArrayList(); 1014 if (intersectsClipArea(tg, converter, clipArea)) { 1015 render_GE(tg, shapeInfos, modifierShapeInfos, converter, clipArea, context); 1016 } 1017 mss.setSymbolShapes(shapeInfos); 1018 mss.setModifierShapes(modifierShapeInfos); 1019 } catch (Exception exc) { 1020 ErrorLogger.LogException("clsRenderer", "renderWithPolylines", 1021 new RendererException("Failed inside renderWithPolylines", exc)); 1022 } 1023 } 1024 1025 /** 1026 * GoogleEarth renderer uses polylines for rendering 1027 * 1028 * @param mss MilStdSymbol object 1029 * @param converter the geographic to pixels coordinate converter 1030 * @param clipArea the clip bounds 1031 */ 1032 public static void renderWithPolylines(MilStdSymbol mss, 1033 IPointConversion converter, 1034 Object clipArea) { 1035 try { 1036 TGLight tg = clsRenderer.createTGLightFromMilStdSymbol(mss, converter); 1037 ArrayList<ShapeInfo> shapeInfos = new ArrayList(); 1038 ArrayList<ShapeInfo> modifierShapeInfos = new ArrayList(); 1039 if (intersectsClipArea(tg, converter, clipArea)) { 1040 render_GE(tg, shapeInfos, modifierShapeInfos, converter, clipArea); 1041 } 1042 mss.setSymbolShapes(shapeInfos); 1043 mss.setModifierShapes(modifierShapeInfos); 1044 mss.set_WasClipped(tg.get_WasClipped()); 1045 } catch (Exception exc) { 1046 ErrorLogger.LogException("clsRenderer", "renderWithPolylines", 1047 new RendererException("Failed inside renderWithPolylines", exc)); 1048 } 1049 } 1050 1051 /** 1052 * See render_GE below for comments 1053 * 1054 * @param tg 1055 * @param shapeInfos 1056 * @param modifierShapeInfos 1057 * @param converter 1058 * @param clipArea 1059 * @param context test android-gradle 1060 * @deprecated context not used 1061 */ 1062 public static void render_GE(TGLight tg, 1063 ArrayList<ShapeInfo> shapeInfos, 1064 ArrayList<ShapeInfo> modifierShapeInfos, 1065 IPointConversion converter, 1066 Object clipArea, 1067 Context context) //was Rectangle2D 1068 { 1069 render_GE(tg, shapeInfos, modifierShapeInfos, converter, clipArea); 1070 } 1071 1072 /** 1073 * Google Earth renderer: Called by mapfragment-demo This is the public 1074 * interface for Google Earth renderer assumes tg.Pixels is filled assumes 1075 * the caller instantiated the ShapeInfo arrays 1076 * 1077 * @param tg tactical graphic 1078 * @param shapeInfos symbol ShapeInfo array 1079 * @param modifierShapeInfos modifier ShapeInfo array 1080 * @param converter geographic to pixels coordinate converter 1081 * @param clipArea clipping bounds in pixels 1082 */ 1083 public static void render_GE(TGLight tg, 1084 ArrayList<ShapeInfo> shapeInfos, 1085 ArrayList<ShapeInfo> modifierShapeInfos, 1086 IPointConversion converter, 1087 Object clipArea) { 1088 try { 1089 reversePointsRevD(tg); 1090 1091 Rectangle2D clipBounds = null; 1092 CELineArray.setClient("ge"); 1093// ArrayList<POINT2> origPixels = null; 1094// ArrayList<POINT2> origLatLongs = null; 1095// if (clsUtilityGE.segmentColorsSet(tg)) { 1096// origPixels=lineutility.getDeepCopy(tg.Pixels); 1097// origLatLongs=lineutility.getDeepCopy(tg.LatLongs); 1098// } 1099 ArrayList<POINT2> origFillPixels = lineutility.getDeepCopy(tg.Pixels); 1100 1101 if (tg.get_LineType() == TacticalLines.LC || tg.get_LineType() == TacticalLines.LC_HOSTILE) 1102 armyc2.c5isr.JavaTacticalRenderer.clsUtility.SegmentLCPoints(tg, converter); 1103 1104// boolean shiftLines = Channels.getShiftLines(); 1105// if (shiftLines) { 1106// String affiliation = tg.get_Affiliation(); 1107// Channels.setAffiliation(affiliation); 1108// } 1109 //CELineArray.setMinLength(2.5); //2-27-2013 1110 ArrayList<Point2D> clipPoints = null; 1111 if (clipArea != null) { 1112 if (clipArea.getClass().isAssignableFrom(Rectangle2D.Double.class)) { 1113 clipBounds = (Rectangle2D.Double) clipArea; 1114 } else if (clipArea.getClass().isAssignableFrom(Rectangle.class)) { 1115 Rectangle rectx = (Rectangle) clipArea; 1116 clipBounds = new Rectangle2D.Double(rectx.x, rectx.y, rectx.width, rectx.height); 1117 } else if (clipArea.getClass().isAssignableFrom(ArrayList.class)) { 1118 clipPoints = (ArrayList<Point2D>) clipArea; 1119 } 1120 } 1121 double zoomFactor = clsUtilityGE.getZoomFactor(clipBounds, clipPoints, tg.Pixels); 1122 //add sub-section to test clipArea if client passes the rectangle 1123 boolean useClipPoints = false; //currently not used 1124 if (useClipPoints == true && clipBounds != null) { 1125 double x = clipBounds.getMinX(); 1126 double y = clipBounds.getMinY(); 1127 double width = clipBounds.getWidth(); 1128 double height = clipBounds.getHeight(); 1129 clipPoints = new ArrayList(); 1130 clipPoints.add(new Point2D.Double(x, y)); 1131 clipPoints.add(new Point2D.Double(x + width, y)); 1132 clipPoints.add(new Point2D.Double(x + width, y + height)); 1133 clipPoints.add(new Point2D.Double(x, y + height)); 1134 clipPoints.add(new Point2D.Double(x, y)); 1135 clipBounds = null; 1136 } 1137 //end section 1138 1139 if (tg.get_Client() == null || tg.get_Client().isEmpty()) { 1140 tg.set_client("ge"); 1141 } 1142 1143 clsUtility.RemoveDuplicatePoints(tg); 1144 1145 int linetype = tg.get_LineType(); 1146 if (linetype < 0) { 1147 linetype = armyc2.c5isr.JavaTacticalRenderer.clsUtility.GetLinetypeFromString(tg.get_SymbolId()); 1148 //clsUtilityCPOF.SegmentGeoPoints(tg, converter); 1149 tg.set_LineType(linetype); 1150 } 1151 1152 Boolean isTextFlipped = false; 1153 ArrayList<Shape2> shapes = null; //use this to collect all the shapes 1154 clsUtilityGE.setSplineLinetype(tg); 1155 setHostileLC(tg); 1156 1157 clsUtilityCPOF.SegmentGeoPoints(tg, converter, zoomFactor); 1158 if (clipBounds != null || clipPoints != null) { 1159 if (clsUtilityCPOF.canClipPoints(tg)) { 1160 //check assignment 1161 if (clipBounds != null) { 1162 clsClipPolygon2.ClipPolygon(tg, clipBounds); 1163 } else if (clipPoints != null) { 1164 clsClipQuad.ClipPolygon(tg, clipPoints); 1165 } 1166 1167 clsUtilityGE.removeTrailingPoints(tg, clipArea); 1168 tg.LatLongs = clsUtility.PixelsToLatLong(tg.Pixels, converter); 1169 } 1170 } 1171 1172 //if MSR segment data set use original pixels unless tg.Pixels is empty from clipping 1173// if (origPixels != null) { 1174// if (tg.Pixels.isEmpty()) { 1175// return; 1176// } else { 1177// tg.Pixels = origPixels; 1178// tg.LatLongs = origLatLongs; 1179// clipArea = null; 1180// } 1181// } 1182 armyc2.c5isr.JavaTacticalRenderer.clsUtility.InterpolatePixels(tg); 1183 1184 tg.modifiers = new ArrayList(); 1185 BufferedImage bi = new BufferedImage(8, 8, BufferedImage.TYPE_INT_ARGB); 1186 Graphics2D g2d = bi.createGraphics(); 1187 g2d.setFont(tg.get_Font()); 1188 Modifier2.AddModifiersGeo(tg, g2d, clipArea, converter); 1189 1190 clsUtilityCPOF.FilterPoints2(tg, converter); 1191 armyc2.c5isr.JavaTacticalRenderer.clsUtility.FilterVerticalSegments(tg); 1192 clsUtility.FilterAXADPoints(tg, converter); 1193 clsUtilityCPOF.ClearPixelsStyle(tg); 1194 1195 ArrayList<Shape2> linesWithFillShapes = null; 1196 1197 ArrayList<POINT2> savePixels = tg.Pixels; 1198 tg.Pixels = origFillPixels; 1199 1200 //check assignment 1201 if (clipBounds != null) { 1202 linesWithFillShapes = clsClipPolygon2.LinesWithFill(tg, clipBounds); 1203 } else if (clipPoints != null) { 1204 linesWithFillShapes = clsClipQuad.LinesWithFill(tg, clipPoints); 1205 } else if (clipArea == null) { 1206 linesWithFillShapes = clsClipPolygon2.LinesWithFill(tg, null); 1207 } 1208 1209 tg.Pixels = savePixels; 1210 1211 ArrayList<Shape2> rangeFanFillShapes = null; 1212 //do not fill the original shapes for circular range fans 1213 int savefillStyle = tg.get_FillStyle(); 1214 if (linetype == TacticalLines.RANGE_FAN) { 1215 tg.set_Fillstyle(0); 1216 } 1217 1218 //check assignment (pass which clip object is not null) 1219 if (clipBounds != null) { 1220 shapes = clsRenderer2.GetLineArray(tg, converter, isTextFlipped, clipBounds); //takes clip object 1221 } else if (clipPoints != null) { 1222 shapes = clsRenderer2.GetLineArray(tg, converter, isTextFlipped, clipPoints); 1223 } else if (clipArea == null) { 1224 shapes = clsRenderer2.GetLineArray(tg, converter, isTextFlipped, null); 1225 } 1226 1227 // Add Feint, decoy, or dummy indicator 1228 if (shapes != null 1229 && SymbolID.getSymbolSet(tg.get_SymbolId()) == SymbolID.SymbolSet_ControlMeasure 1230 && SymbolUtilities.hasFDI(tg.get_SymbolId())) { 1231 addFDI(tg, shapes); 1232 } 1233 1234 switch (linetype) { 1235 case TacticalLines.RANGE_FAN: 1236 case TacticalLines.RANGE_FAN_SECTOR: 1237 case TacticalLines.RADAR_SEARCH: 1238 if (tg.get_FillColor() == null || tg.get_FillColor().getAlpha() < 2) { 1239 break; 1240 } 1241 TGLight tg1 = clsUtilityCPOF.GetCircularRangeFanFillTG(tg); 1242 tg1.set_Fillstyle(savefillStyle); 1243 tg1.set_SymbolId(tg.get_SymbolId()); 1244 //check assignment (pass which clip object is not null) 1245 if (clipBounds != null) { 1246 rangeFanFillShapes = clsRenderer2.GetLineArray(tg1, converter, isTextFlipped, clipBounds); 1247 } else if (clipPoints != null) { 1248 rangeFanFillShapes = clsRenderer2.GetLineArray(tg1, converter, isTextFlipped, clipPoints); 1249 } else if (clipArea == null) { 1250 rangeFanFillShapes = clsRenderer2.GetLineArray(tg1, converter, isTextFlipped, null); 1251 } 1252 1253 if (rangeFanFillShapes != null) { 1254 if (shapes == null) { 1255 System.out.println("shapes is null"); 1256 break; 1257 } else { 1258 shapes.addAll(0, rangeFanFillShapes); 1259 } 1260 1261 } 1262 break; 1263 default: 1264 clsRenderer2.getAutoshapeFillShape(tg, shapes); 1265 break; 1266 } 1267 //end section 1268 1269 //undo any fillcolor for lines with fill 1270 clsUtilityCPOF.LinesWithSeparateFill(tg.get_LineType(), shapes); 1271 clsClipPolygon2.addAbatisFill(tg, shapes); 1272 1273 //if this line is commented then the extra line in testbed goes away 1274 if (shapes != null && linesWithFillShapes != null && linesWithFillShapes.size() > 0) { 1275 shapes.addAll(0, linesWithFillShapes); 1276 } 1277 1278 if (clsUtilityCPOF.canClipPoints(tg) == false && clipBounds != null) { 1279 shapes = clsUtilityCPOF.postClipShapes(tg, shapes, clipBounds); 1280 } else if (clsUtilityCPOF.canClipPoints(tg) == false && clipPoints != null) { 1281 shapes = clsUtilityCPOF.postClipShapes(tg, shapes, clipPoints); 1282 } 1283 //returns early if textSpecs are null 1284 //currently the client is ignoring these 1285 if (modifierShapeInfos != null) { 1286 ArrayList<Shape2> textSpecs = new ArrayList(); 1287 Modifier2.DisplayModifiers2(tg, g2d, textSpecs, isTextFlipped, converter); 1288 Shape2ToShapeInfo(modifierShapeInfos, textSpecs); 1289 } 1290 Shape2ToShapeInfo(shapeInfos, shapes); 1291 clsUtility.addHatchFills(tg, shapeInfos); 1292 1293 //check assignment (pass which clip object is not null) 1294 if (clipBounds != null) { 1295 clsUtilityGE.SetShapeInfosPolylines(tg, shapeInfos, clipBounds);//takes a clip object 1296 } else if (clipPoints != null) { 1297 clsUtilityGE.SetShapeInfosPolylines(tg, shapeInfos, clipPoints); 1298 } else if (clipArea == null) { 1299 clsUtilityGE.SetShapeInfosPolylines(tg, shapeInfos, null); 1300 } 1301 } catch (Exception exc) { 1302 ErrorLogger.LogException(_className, "render_GE", 1303 new RendererException("Failed inside render_GE", exc)); 1304 1305 } 1306 } 1307 /** 1308 * creates a shape for known symbols. The intent is to use client points for 1309 * the shape and is intended for use with ellipse. If hatch > 1 it creates 2 shapes 1310 * one for the hatch pattern, the second one is for the outline. 1311 * 1312 * @param milStd 1313 * @param ipc 1314 * @param clipArea 1315 * @param shapeType 1316 * @param lineColor 1317 * @param fillColor 1318 * @param hatch 1319 */ 1320 public static void render_Shape(MilStdSymbol milStd, 1321 IPointConversion ipc, 1322 Object clipArea, 1323 int shapeType, 1324 Color lineColor, 1325 Color fillColor, 1326 int hatch) { 1327 try { 1328 Rectangle2D clipBounds = null; 1329 //CELineArray.setClient("ge"); 1330 ArrayList<Point2D> clipPoints = null; 1331 1332 if (clipArea != null) { 1333 if (clipArea.getClass().isAssignableFrom(Rectangle2D.Double.class)) { 1334 clipBounds = (Rectangle2D.Double) clipArea; 1335 } else if (clipArea.getClass().isAssignableFrom(Rectangle.class)) { 1336 clipBounds = (Rectangle2D) clipArea; 1337 } else if (clipArea.getClass().isAssignableFrom(ArrayList.class)) { 1338 clipPoints = (ArrayList<Point2D>) clipArea; 1339 } 1340 } 1341 1342 //can't use following line because it resets the pixels 1343 //TGLight tg = createTGLightFromMilStdSymbol(milStd, ipc); 1344 TGLight tg = new TGLight(); 1345 tg.set_SymbolId(milStd.getSymbolID()); 1346 //tg.set_VisibleModifiers(true); 1347 //set tg latlongs and pixels 1348 setClientCoords(milStd, tg); 1349 //build tg.Pixels 1350 tg.Pixels = clsUtility.LatLongToPixels(tg.LatLongs, ipc); 1351 1352 //int fillStyle = milStd.getPatternFillType(); 1353 Shape2 shape = new Shape2(shapeType); 1354 shape.setFillColor(fillColor); 1355 if (lineColor != null) { 1356 shape.setLineColor(lineColor); 1357 shape.setStroke(new BasicStroke(milStd.getLineWidth())); 1358 } 1359 //the client has already set the coordinates for the shape 1360 POINT2 pt; 1361 for (int j = 0; j < tg.Pixels.size(); j++) { 1362 pt = tg.Pixels.get(j); 1363 if (j == 0) { 1364 shape.moveTo(pt); 1365 } else { 1366 shape.lineTo(pt); 1367 } 1368 } 1369 1370 //post clip the shape and set the polylines 1371 ArrayList<Shape2> shapes = new ArrayList(); 1372 shapes.add(shape); 1373 //post-clip the shape 1374 if (clsUtilityCPOF.canClipPoints(tg) == false && clipBounds != null) { 1375 shapes = clsUtilityCPOF.postClipShapes(tg, shapes, clipBounds); 1376 } else if (clsUtilityCPOF.canClipPoints(tg) == false && clipPoints != null) { 1377 shapes = clsUtilityCPOF.postClipShapes(tg, shapes, clipPoints); 1378 } 1379 shape=shapes.get(0); 1380 if (hatch > 1) 1381 { 1382 shape = clsUtility.buildHatchArea(tg, shape, hatch, 20); 1383 shape.setLineColor(lineColor); 1384 shape.setStroke(new BasicStroke(1)); 1385 //shapes.clear(); 1386 shapes.add(shape); 1387 } 1388 ArrayList<ShapeInfo> shapeInfos = new ArrayList(); 1389 Shape2ToShapeInfo(shapeInfos, shapes); 1390 //set the shapeInfo polylines 1391 if (clipBounds != null) { 1392 clsUtilityGE.SetShapeInfosPolylines(tg, shapeInfos, clipBounds); 1393 } else if (clipPoints != null) { 1394 clsUtilityGE.SetShapeInfosPolylines(tg, shapeInfos, clipPoints); 1395 } else if (clipArea == null) { 1396 clsUtilityGE.SetShapeInfosPolylines(tg, shapeInfos, null); 1397 } 1398 //set milStd symbol shapes 1399 if (milStd.getSymbolShapes() == null) { 1400 milStd.setSymbolShapes(shapeInfos); 1401 } else { 1402 milStd.getSymbolShapes().addAll(shapeInfos); 1403 } 1404 return; 1405 } catch (Exception exc) { 1406 ErrorLogger.LogException(_className, "render_Shape", 1407 new RendererException("Failed inside render_Shape", exc)); 1408 1409 } 1410 } 1411 /** 1412 * to follow right hand rule for LC when affiliation is hostile. also fixes 1413 * MSDZ point order and maybe various other wayward symbols 1414 * 1415 * @param tg 1416 */ 1417 private static void setHostileLC(TGLight tg) { 1418 try { 1419 Boolean usas1314 = true; 1420 ArrayList<POINT2> pts = new ArrayList(); 1421 int j = 0; 1422 switch (tg.get_LineType()) { 1423 case TacticalLines.LC: 1424 if (usas1314 == false) { 1425 break; 1426 } 1427 if (!tg.isHostile()) { 1428 break; 1429 } 1430 pts = (ArrayList<POINT2>) tg.Pixels.clone(); 1431 for (j = 0; j < tg.Pixels.size(); j++) { 1432 tg.Pixels.set(j, pts.get(pts.size() - j - 1)); 1433 } 1434 //reverse the latlongs also 1435 pts = (ArrayList<POINT2>) tg.LatLongs.clone(); 1436 for (j = 0; j < tg.LatLongs.size(); j++) { 1437 tg.LatLongs.set(j, pts.get(pts.size() - j - 1)); 1438 } 1439 break; 1440 case TacticalLines.LINE: //CPOF client requests reverse orientation 1441 pts = (ArrayList<POINT2>) tg.Pixels.clone(); 1442 for (j = 0; j < tg.Pixels.size(); j++) { 1443 tg.Pixels.set(j, pts.get(pts.size() - j - 1)); 1444 } 1445 //reverse the latlongs also 1446 pts = (ArrayList<POINT2>) tg.LatLongs.clone(); 1447 for (j = 0; j < tg.LatLongs.size(); j++) { 1448 tg.LatLongs.set(j, pts.get(pts.size() - j - 1)); 1449 } 1450 break; 1451 default: 1452 return; 1453 } 1454 } catch (Exception exc) { 1455 ErrorLogger.LogException(_className, "setHostileLC", 1456 new RendererException("Failed inside setHostileLC", exc)); 1457 1458 } 1459 } 1460 1461 /** 1462 * set the clip rectangle as an arraylist or a Rectangle2D depending on the 1463 * object 1464 * 1465 * @param clipBounds 1466 * @param clipRect 1467 * @param clipArray 1468 * @return 1469 */ 1470 private static boolean setClip(Object clipBounds, Rectangle2D clipRect, ArrayList<Point2D> clipArray) { 1471 try { 1472 if (clipBounds == null) { 1473 return false; 1474 } else if (clipBounds.getClass().isAssignableFrom(Rectangle2D.Double.class)) { 1475 clipRect.setRect((Rectangle2D) clipBounds); 1476 } else if (clipBounds.getClass().isAssignableFrom(Rectangle2D.class)) { 1477 clipRect.setRect((Rectangle2D) clipBounds); 1478 } else if (clipBounds.getClass().isAssignableFrom(Rectangle.class)) { 1479 //clipRect.setRect((Rectangle2D)clipBounds); 1480 Rectangle rectx = (Rectangle) clipBounds; 1481 //clipBounds=new Rectangle2D.Double(rectx.x,rectx.y,rectx.width,rectx.height); 1482 clipRect.setRect(rectx.x, rectx.y, rectx.width, rectx.height); 1483 } else if (clipBounds.getClass().isAssignableFrom(ArrayList.class)) { 1484 clipArray.addAll((ArrayList) clipBounds); 1485 } 1486 } catch (Exception exc) { 1487 ErrorLogger.LogException(_className, "setClip", 1488 new RendererException("Failed inside setClip", exc)); 1489 1490 } 1491 return true; 1492 } 1493 1494 /** 1495 * public render function transferred from JavaLineArrayCPOF project. Use 1496 * this function to replicate CPOF renderer functionality. 1497 * 1498 * @param mss the milStdSymbol object 1499 * @param converter the geographic to pixels coordinate converter 1500 * @param clipBounds the pixels based clip bounds 1501 */ 1502 public static void render(MilStdSymbol mss, 1503 IPointConversion converter, 1504 Object clipBounds) { 1505 try { 1506 ArrayList<ShapeInfo> shapeInfos = new ArrayList(); 1507 ArrayList<ShapeInfo> modifierShapeInfos = new ArrayList(); 1508 render(mss, converter, shapeInfos, modifierShapeInfos, clipBounds); 1509 } catch (Exception exc) { 1510 ErrorLogger.LogException(_className, "render", 1511 new RendererException("render", exc)); 1512 1513 } 1514 } 1515 1516 /** 1517 * Generic tester button says Tiger or use JavaRendererSample. Generic 1518 * renderer testers: called by JavaRendererSample and TestJavaLineArray 1519 * public render function transferred from JavaLineArrayCPOF project. Use 1520 * this function to replicate CPOF renderer functionality. 1521 * 1522 * @param mss 1523 * @param converter geographic to pixels converter 1524 * @param shapeInfos ShapeInfo array 1525 * @param modifierShapeInfos modifier ShapeInfo array 1526 * @param clipBounds clip bounds 1527 */ 1528 public static void render(MilStdSymbol mss, 1529 IPointConversion converter, 1530 ArrayList<ShapeInfo> shapeInfos, 1531 ArrayList<ShapeInfo> modifierShapeInfos, 1532 Object clipBounds) { 1533 try { 1534 //boolean shiftLines = Channels.getShiftLines(); 1535 //end section 1536 1537 Rectangle2D clipRect = new Rectangle2D.Double(); 1538 ArrayList<Point2D> clipArray = new ArrayList(); 1539 setClip(clipBounds, clipRect, clipArray); 1540 1541 TGLight tg = createTGLightFromMilStdSymbol(mss, converter); 1542 reversePointsRevD(tg); 1543 CELineArray.setClient("generic"); 1544// if (shiftLines) { 1545// String affiliation = tg.get_Affiliation(); 1546// Channels.setAffiliation(affiliation); 1547// } 1548 //CELineArray.setMinLength(2.5); //2-27-2013 1549 1550 int linetype = tg.get_LineType(); 1551 //replace calls to MovePixels 1552 clsUtility.RemoveDuplicatePoints(tg); 1553 1554 setHostileLC(tg); 1555 1556 BufferedImage bi = new BufferedImage(8, 8, BufferedImage.TYPE_INT_ARGB); 1557 Graphics2D g2d = bi.createGraphics(); 1558 g2d.setFont(tg.get_Font()); 1559 1560 clsUtilityCPOF.SegmentGeoPoints(tg, converter, 1); 1561 clsUtility.FilterAXADPoints(tg, converter); 1562 1563 //prevent vertical segments for oneway, twoway, alt 1564 armyc2.c5isr.JavaTacticalRenderer.clsUtility.FilterVerticalSegments(tg); 1565 boolean isChange1Area = armyc2.c5isr.JavaTacticalRenderer.clsUtility.IsChange1Area(linetype); 1566 boolean isTextFlipped = false; 1567 //for 3d change 1 symbols we do not transform the points 1568 1569 //if it is world view then we want to flip the far points about 1570 //the left and right sides to get two symbols 1571 ArrayList<POINT2> farLeftPixels = new ArrayList(); 1572 ArrayList<POINT2> farRightPixels = new ArrayList(); 1573 if (isChange1Area == false) { 1574 clsUtilityCPOF.GetFarPixels(tg, converter, farLeftPixels, farRightPixels); 1575 } 1576 1577 ArrayList<Shape2> shapesLeft = new ArrayList(); 1578 ArrayList<Shape2> shapesRight = new ArrayList(); 1579 ArrayList<Shape2> shapes = null; //use this to collect all the shapes 1580 1581 //CPOF 6.0 diagnostic 1582 ArrayList<Shape2> textSpecsLeft = null; 1583 ArrayList<Shape2> textSpecsRight = null; 1584 //Note: DisplayModifiers3 returns early if textSpecs are null 1585 textSpecsLeft = new ArrayList(); 1586 textSpecsRight = new ArrayList(); 1587 1588 if (farLeftPixels.size() > 0) { 1589 tg.Pixels = farLeftPixels; 1590 shapesLeft = clsRenderer2.GetLineArray(tg, converter, isTextFlipped, clipBounds); 1591 //CPOF 6.0 1592 //returns early if textSpecs are null 1593 Modifier2.DisplayModifiers2(tg, g2d, textSpecsLeft, isTextFlipped, null); 1594 } 1595 if (farRightPixels.size() > 0) { 1596 tg.Pixels = farRightPixels; 1597 shapesRight = clsRenderer2.GetLineArray(tg, converter, isTextFlipped, clipBounds); 1598 //CPOF 6.0 1599 //returns early if textSpecs are null 1600 Modifier2.DisplayModifiers2(tg, g2d, textSpecsRight, isTextFlipped, null); 1601 } 1602 1603 //CPOF 6.0 diagnostic 1604 ArrayList<Shape2> textSpecs = new ArrayList(); 1605 1606 if (shapesLeft.isEmpty() || shapesRight.isEmpty()) { 1607 ArrayList<Shape2> linesWithFillShapes = null; 1608 if (clipArray != null && !clipArray.isEmpty()) { 1609 linesWithFillShapes = clsClipQuad.LinesWithFill(tg, clipArray); 1610 } else if (clipRect != null && clipRect.getWidth() != 0) { 1611 linesWithFillShapes = clsClipPolygon2.LinesWithFill(tg, clipRect); 1612 } else { 1613 linesWithFillShapes = clsClipPolygon2.LinesWithFill(tg, null); 1614 } 1615 1616 //diagnostic: comment two lines if using the WW tester 1617 if (clsUtilityCPOF.canClipPoints(tg) && clipBounds != null) { 1618 if (clipArray != null && !clipArray.isEmpty()) { 1619 clsClipQuad.ClipPolygon(tg, clipArray); 1620 } else if (clipRect != null && clipRect.getWidth() != 0) { 1621 clsClipPolygon2.ClipPolygon(tg, clipRect); 1622 } 1623 1624 tg.LatLongs = clsUtility.PixelsToLatLong(tg.Pixels, converter); 1625 } 1626 1627 //diagnostic 1-28-13 1628 armyc2.c5isr.JavaTacticalRenderer.clsUtility.InterpolatePixels(tg); 1629 1630 tg.modifiers = new ArrayList(); 1631 Modifier2.AddModifiersGeo(tg, g2d, clipBounds, converter); 1632 1633 clsUtilityCPOF.FilterPoints2(tg, converter); 1634 clsUtilityCPOF.ClearPixelsStyle(tg); 1635 //add section to replace preceding line M. Deutch 11-4-2011 1636 ArrayList rangeFanFillShapes = null; 1637 //do not fill the original shapes for circular range fans 1638 int savefillStyle = tg.get_FillStyle(); 1639 if (linetype == TacticalLines.RANGE_FAN) { 1640 tg.set_Fillstyle(0); 1641 } 1642 1643 shapes = clsRenderer2.GetLineArray(tg, converter, isTextFlipped, clipBounds); 1644 1645 // Add Feint, decoy, or dummy indicator 1646 if (shapes != null 1647 && SymbolID.getSymbolSet(tg.get_SymbolId()) == SymbolID.SymbolSet_ControlMeasure 1648 && SymbolUtilities.hasFDI(tg.get_SymbolId())) { 1649 addFDI(tg, shapes); 1650 } 1651 1652 switch (linetype) { 1653 case TacticalLines.RANGE_FAN: 1654 case TacticalLines.RANGE_FAN_SECTOR: 1655 case TacticalLines.RADAR_SEARCH: 1656 if (tg.get_FillColor() == null || tg.get_FillColor().getAlpha() < 2) { 1657 break; 1658 } 1659 TGLight tg1 = clsUtilityCPOF.GetCircularRangeFanFillTG(tg); 1660 tg1.set_Fillstyle(savefillStyle); 1661 tg1.set_SymbolId(tg.get_SymbolId()); 1662 rangeFanFillShapes = clsRenderer2.GetLineArray(tg1, converter, isTextFlipped, clipBounds); 1663 1664 if (rangeFanFillShapes != null) { 1665 shapes.addAll(0, rangeFanFillShapes); 1666 } 1667 break; 1668 default: 1669 break; 1670 } 1671 1672 //undo any fillcolor for lines with fill 1673 clsUtilityCPOF.LinesWithSeparateFill(tg.get_LineType(), shapes); 1674 clsClipPolygon2.addAbatisFill(tg, shapes); 1675 1676 //if this line is commented then the extra line in testbed goes away 1677 if (shapes != null && linesWithFillShapes != null && linesWithFillShapes.size() > 0) { 1678 shapes.addAll(0, linesWithFillShapes); 1679 } 1680 1681 if (shapes != null && shapes.size() > 0) { 1682 Modifier2.DisplayModifiers2(tg, g2d, textSpecs, isTextFlipped, null); 1683 Shape2ToShapeInfo(modifierShapeInfos, textSpecs); 1684 mss.setModifierShapes(modifierShapeInfos); 1685 } 1686 } else //symbol was more than 180 degrees wide, use left and right symbols 1687 { 1688 shapes = shapesLeft; 1689 shapes.addAll(shapesRight); 1690 1691 if (textSpecs != null) { 1692 textSpecs.addAll(textSpecsLeft); 1693 textSpecs.addAll(textSpecsRight); 1694 } 1695 } 1696 //post-clip the points if the tg could not be pre-clipped 1697 if (clsUtilityCPOF.canClipPoints(tg) == false && clipBounds != null) { 1698 shapes = clsUtilityCPOF.postClipShapes(tg, shapes, clipBounds); 1699 } 1700 1701 Shape2ToShapeInfo(shapeInfos, shapes); 1702 clsUtility.addHatchFills(tg, shapeInfos); 1703 mss.setSymbolShapes(shapeInfos); 1704 } catch (Exception exc) { 1705 ErrorLogger.LogException(_className, "render", 1706 new RendererException("Failed inside render", exc)); 1707 1708 } 1709 } 1710 1711 public static int getCMLineType(int version, int entityCode) { 1712 // Check if line type is specific to a version 1713 if (version == SymbolID.Version_2525E){ 1714 switch (entityCode) { 1715 // Added in 2525E 1716 case 110400: 1717 return TacticalLines.GENERIC_LINE; 1718 case 120700: 1719 return TacticalLines.GENERIC_AREA; 1720 case 141800: 1721 return TacticalLines.HOL; 1722 case 141900: 1723 return TacticalLines.BHL; 1724 case 310800: 1725 return TacticalLines.CSA; 1726 case 330500: 1727 return TacticalLines.ROUTE; 1728 case 330501: 1729 return TacticalLines.ROUTE_ONEWAY; 1730 case 330502: 1731 return TacticalLines.ROUTE_ALT; 1732 case 344100: 1733 return TacticalLines.FPOL; 1734 case 344200: 1735 return TacticalLines.RPOL; 1736 // Updated in 2525E 1737 case 120500: 1738 return TacticalLines.BASE_CAMP; 1739 case 120600: 1740 return TacticalLines.GUERILLA_BASE; 1741 case 151000: 1742 return TacticalLines.FORT; 1743 case 260400: 1744 return TacticalLines.BCL; 1745 case 310100: 1746 return TacticalLines.DHA; 1747 } 1748 } else { // 2525Dchange 1 and older 1749 switch (entityCode) { 1750 // Updated in 2525E 1751 case 120500: 1752 return TacticalLines.BASE_CAMP_REVD; 1753 case 120600: 1754 return TacticalLines.GUERILLA_BASE_REVD; 1755 case 151000: 1756 return TacticalLines.FORT_REVD; 1757 case 260400: 1758 return TacticalLines.BCL_REVD; 1759 case 310100: 1760 return TacticalLines.DHA_REVD; 1761 // Removed in 2525E 1762 case 150300: 1763 return TacticalLines.ASSY; 1764 case 241601: 1765 return TacticalLines.SENSOR; 1766 case 241602: 1767 return TacticalLines.SENSOR_RECTANGULAR; 1768 case 241603: 1769 return TacticalLines.SENSOR_CIRCULAR; 1770 } 1771 } 1772 // Line type isn't specific to a version or doesn't exist 1773 switch (entityCode) { 1774 case 200101: 1775 return TacticalLines.LAUNCH_AREA; 1776 case 200201: 1777 return TacticalLines.DEFENDED_AREA_CIRCULAR; 1778 case 200202: 1779 return TacticalLines.DEFENDED_AREA_RECTANGULAR; 1780 case 120100: 1781 return TacticalLines.AO; 1782 case 120200: 1783 return TacticalLines.NAI; 1784 case 120300: 1785 return TacticalLines.TAI; 1786 case 120400: 1787 return TacticalLines.AIRFIELD; 1788 case 151401: 1789 return TacticalLines.AIRAOA; 1790 case 151402: 1791 return TacticalLines.AAAAA; 1792 case 151403: 1793 return TacticalLines.MAIN; 1794 case 151404: 1795 return TacticalLines.SPT; 1796 case 110100: 1797 return TacticalLines.BOUNDARY; 1798 case 110200: 1799 return TacticalLines.LL; 1800 case 110300: 1801 return TacticalLines.EWL; 1802 case 140100: 1803 return TacticalLines.FLOT; 1804 case 140200: 1805 return TacticalLines.LC; 1806 case 140300: 1807 return TacticalLines.PL; 1808 case 140400: 1809 return TacticalLines.FEBA; 1810 case 140500: 1811 return TacticalLines.PDF; 1812 case 140601: 1813 return TacticalLines.DIRATKAIR; 1814 case 140602: 1815 return TacticalLines.DIRATKGND; 1816 case 140603: 1817 return TacticalLines.DIRATKSPT; 1818 case 140700: 1819 return TacticalLines.FCL; 1820 case 140800: 1821 return TacticalLines.IL; 1822 case 140900: 1823 return TacticalLines.LOA; 1824 case 141000: 1825 return TacticalLines.LOD; 1826 case 141100: 1827 return TacticalLines.LDLC; 1828 case 141200: 1829 return TacticalLines.PLD; 1830 case 150200: 1831 return TacticalLines.ASSY; 1832 case 150100: 1833 return TacticalLines.GENERAL; 1834 case 150501: 1835 return TacticalLines.JTAA; 1836 case 150502: 1837 return TacticalLines.SAA; 1838 case 150503: 1839 return TacticalLines.SGAA; 1840 case 150600: //dz no eny 1841 return TacticalLines.DZ; 1842 case 150700: //ez no eny 1843 return TacticalLines.EZ; 1844 case 150800: //lz no eny 1845 return TacticalLines.LZ; 1846 case 150900: //pz no eny 1847 return TacticalLines.PZ; 1848 case 151100: 1849 return TacticalLines.LAA; 1850 case 151200: 1851 return TacticalLines.BATTLE; 1852 case 151202: 1853 return TacticalLines.PNO; 1854 case 151204: 1855 return TacticalLines.CONTAIN; 1856 case 151205: 1857 return TacticalLines.RETAIN; 1858 case 151300: 1859 return TacticalLines.EA; 1860 case 151203: 1861 return TacticalLines.STRONG; 1862 case 151500: 1863 return TacticalLines.ASSAULT; 1864 case 151600: 1865 return TacticalLines.ATKPOS; 1866 case 151700: 1867 return TacticalLines.OBJ; 1868 case 151800: 1869 return TacticalLines.ENCIRCLE; 1870 case 151900: 1871 return TacticalLines.PEN; 1872 case 152000: 1873 return TacticalLines.ATKBYFIRE; 1874 case 152100: 1875 return TacticalLines.SPTBYFIRE; 1876 case 152200: 1877 return TacticalLines.SARA; 1878 case 141300: 1879 return TacticalLines.AIRHEAD; 1880 case 141400: 1881 return TacticalLines.BRDGHD; 1882 case 141500: 1883 return TacticalLines.HOLD; 1884 case 141600: 1885 return TacticalLines.RELEASE; 1886 case 141700: 1887 return TacticalLines.AMBUSH; 1888 case 170100: 1889 return TacticalLines.AC; 1890 case 170200: 1891 return TacticalLines.LLTR; 1892 case 170300: 1893 return TacticalLines.MRR; 1894 case 170400: 1895 return TacticalLines.SL; 1896 case 170500: 1897 return TacticalLines.SAAFR; 1898 case 170600: 1899 return TacticalLines.TC; 1900 case 170700: 1901 return TacticalLines.SC; 1902 case 170800: 1903 return TacticalLines.BDZ; 1904 case 170900: 1905 return TacticalLines.HIDACZ; 1906 case 171000: 1907 return TacticalLines.ROZ; 1908 case 171100: 1909 return TacticalLines.AARROZ; 1910 case 171200: 1911 return TacticalLines.UAROZ; 1912 case 171300: 1913 return TacticalLines.WEZ; 1914 case 171400: 1915 return TacticalLines.FEZ; 1916 case 171500: 1917 return TacticalLines.JEZ; 1918 case 171600: 1919 return TacticalLines.MEZ; 1920 case 171700: 1921 return TacticalLines.LOMEZ; 1922 case 171800: 1923 return TacticalLines.HIMEZ; 1924 case 171900: 1925 return TacticalLines.FAADZ; 1926 case 172000: 1927 return TacticalLines.WFZ; 1928 case 200401: 1929 return TacticalLines.SHIP_AOI_CIRCULAR; 1930 case 240804: 1931 return TacticalLines.RECTANGULAR_TARGET; 1932 case 220100: 1933 return TacticalLines.BEARING; 1934 case 220101: 1935 return TacticalLines.ELECTRO; 1936 case 220102: //EW //new label 1937 return TacticalLines.BEARING_EW; 1938 case 220103: 1939 return TacticalLines.ACOUSTIC; 1940 case 220104: 1941 return TacticalLines.ACOUSTIC_AMB; 1942 case 220105: 1943 return TacticalLines.TORPEDO; 1944 case 220106: 1945 return TacticalLines.OPTICAL; 1946 case 218400: 1947 return TacticalLines.NAVIGATION; 1948 case 220107: //Jammer //new label 1949 return TacticalLines.BEARING_J; 1950 case 220108: //RDF //new label 1951 return TacticalLines.BEARING_RDF; 1952 case 240101: 1953 return TacticalLines.ACA; 1954 case 240102: 1955 return TacticalLines.ACA_RECTANGULAR; 1956 case 240103: 1957 return TacticalLines.ACA_CIRCULAR; 1958 1959 case 240201: 1960 return TacticalLines.FFA; 1961 case 240202: 1962 return TacticalLines.FFA_RECTANGULAR; 1963 case 240203: 1964 return TacticalLines.FFA_CIRCULAR; 1965 1966 case 240301: 1967 return TacticalLines.NFA; 1968 case 240302: 1969 return TacticalLines.NFA_RECTANGULAR; 1970 case 240303: 1971 return TacticalLines.NFA_CIRCULAR; 1972 1973 case 240401: 1974 return TacticalLines.RFA; 1975 case 240402: 1976 return TacticalLines.RFA_RECTANGULAR; 1977 case 240403: 1978 return TacticalLines.RFA_CIRCULAR; 1979 case 240503: 1980 return TacticalLines.PAA; 1981 case 240501: 1982 return TacticalLines.PAA_RECTANGULAR; 1983 case 240502: 1984 return TacticalLines.PAA_CIRCULAR; 1985 case 260100: 1986 return TacticalLines.FSCL; 1987 case 300100: 1988 return TacticalLines.ICL; 1989 case 190100: 1990 return TacticalLines.IFF_OFF; 1991 case 190200: 1992 return TacticalLines.IFF_ON; 1993 case 260200: 1994 return TacticalLines.CFL; 1995 case 260300: 1996 return TacticalLines.NFL; 1997 case 260500: 1998 return TacticalLines.RFL; 1999 case 260600: 2000 return TacticalLines.MFP; 2001 case 240701: 2002 return TacticalLines.LINTGT; 2003 case 240702: 2004 return TacticalLines.LINTGTS; 2005 case 240703: 2006 return TacticalLines.FPF; 2007 case 240801: 2008 return TacticalLines.AT; 2009 case 240802: 2010 return TacticalLines.RECTANGULAR; 2011 case 240803: 2012 return TacticalLines.CIRCULAR; 2013 case 240805: 2014 return TacticalLines.SERIES; 2015 case 240806: 2016 return TacticalLines.SMOKE; 2017 case 240808: 2018 return TacticalLines.BOMB; 2019 case 241001: 2020 return TacticalLines.FSA; 2021 case 241002: 2022 return TacticalLines.FSA_RECTANGULAR; 2023 case 200402: 2024 return TacticalLines.SHIP_AOI_RECTANGULAR; 2025 case 200600: 2026 return TacticalLines.CUED_ACQUISITION; 2027 case 200700: 2028 return TacticalLines.RADAR_SEARCH; 2029 case 241003: 2030 return TacticalLines.FSA_CIRCULAR; 2031 case 200300: 2032 return TacticalLines.NOTACK; 2033 case 241101: 2034 return TacticalLines.ATI; 2035 case 241102: 2036 return TacticalLines.ATI_RECTANGULAR; 2037 case 241103: 2038 return TacticalLines.ATI_CIRCULAR; 2039 case 241201: 2040 return TacticalLines.CFFZ; 2041 case 241202: 2042 return TacticalLines.CFFZ_RECTANGULAR; 2043 case 241203: 2044 return TacticalLines.CFFZ_CIRCULAR; 2045 case 241301: 2046 return TacticalLines.CENSOR; 2047 case 241302: 2048 return TacticalLines.CENSOR_RECTANGULAR; 2049 case 241303: 2050 return TacticalLines.CENSOR_CIRCULAR; 2051 case 241401: 2052 return TacticalLines.CFZ; 2053 case 241402: 2054 return TacticalLines.CFZ_RECTANGULAR; 2055 case 241403: 2056 return TacticalLines.CFZ_CIRCULAR; 2057 case 241501: 2058 return TacticalLines.DA; 2059 case 241502: 2060 return TacticalLines.DA_RECTANGULAR; 2061 case 241503: 2062 return TacticalLines.DA_CIRCULAR; 2063 case 241701: 2064 return TacticalLines.TBA; 2065 case 241702: 2066 return TacticalLines.TBA_RECTANGULAR; 2067 case 241703: 2068 return TacticalLines.TBA_CIRCULAR; 2069 case 241801: 2070 return TacticalLines.TVAR; 2071 case 241802: 2072 return TacticalLines.TVAR_RECTANGULAR; 2073 case 241803: 2074 return TacticalLines.TVAR_CIRCULAR; 2075 case 241901: 2076 return TacticalLines.ZOR; 2077 case 241902: 2078 return TacticalLines.ZOR_RECTANGULAR; 2079 case 241903: 2080 return TacticalLines.ZOR_CIRCULAR; 2081 case 242000: 2082 return TacticalLines.TGMF; 2083 case 242100: 2084 return TacticalLines.RANGE_FAN; 2085 case 242200: 2086 return TacticalLines.RANGE_FAN_SECTOR; 2087 case 242301: 2088 return TacticalLines.KILLBOXBLUE; 2089 case 242302: 2090 return TacticalLines.KILLBOXBLUE_RECTANGULAR; 2091 case 242303: 2092 return TacticalLines.KILLBOXBLUE_CIRCULAR; 2093 case 242304: 2094 return TacticalLines.KILLBOXPURPLE; 2095 case 242305: 2096 return TacticalLines.KILLBOXPURPLE_RECTANGULAR; 2097 case 242306: 2098 return TacticalLines.KILLBOXPURPLE_CIRCULAR; 2099 case 270100: 2100 case 270200: 2101 return TacticalLines.ZONE; 2102 case 270300: 2103 return TacticalLines.OBSFAREA; 2104 case 270400: 2105 return TacticalLines.OBSAREA; 2106 case 270501: 2107 return TacticalLines.MNFLDBLK; 2108 case 270502: 2109 return TacticalLines.MNFLDDIS; 2110 case 270503: 2111 return TacticalLines.MNFLDFIX; 2112 case 270504: 2113 return TacticalLines.TURN; 2114 case 270601: 2115 return TacticalLines.EASY; 2116 case 270602: 2117 return TacticalLines.BYDIF; 2118 case 270603: 2119 return TacticalLines.BYIMP; 2120 case 271100: 2121 return TacticalLines.GAP; 2122 case 271201: 2123 return TacticalLines.PLANNED; 2124 case 271202: 2125 return TacticalLines.ESR1; 2126 case 271203: 2127 return TacticalLines.ESR2; 2128 case 271204: 2129 return TacticalLines.ROADBLK; 2130 case 280100: 2131 return TacticalLines.ABATIS; 2132 case 290100: 2133 return TacticalLines.LINE; 2134 case 290201: 2135 return TacticalLines.ATDITCH; 2136 case 290202: 2137 return TacticalLines.ATDITCHC; 2138 case 290203: 2139 return TacticalLines.ATDITCHM; 2140 case 290204: 2141 return TacticalLines.ATWALL; 2142 case 290301: 2143 return TacticalLines.UNSP; 2144 case 290302: 2145 return TacticalLines.SFENCE; 2146 case 290303: 2147 return TacticalLines.DFENCE; 2148 case 290304: 2149 return TacticalLines.DOUBLEA; 2150 case 290305: 2151 return TacticalLines.LWFENCE; 2152 case 290306: 2153 return TacticalLines.HWFENCE; 2154 case 290307: 2155 return TacticalLines.SINGLEC; 2156 case 290308: 2157 return TacticalLines.DOUBLEC; 2158 case 290309: 2159 return TacticalLines.TRIPLE; 2160 case 290600: 2161 return TacticalLines.MFLANE; 2162 case 270707: 2163 return TacticalLines.DEPICT; 2164 case 270800: 2165 return TacticalLines.MINED; 2166 case 270801: 2167 return TacticalLines.FENCED; 2168 case 290101: 2169 return TacticalLines.MINE_LINE; 2170 case 271000: 2171 return TacticalLines.UXO; 2172 case 271700: 2173 return TacticalLines.BIO; 2174 case 271800: 2175 return TacticalLines.CHEM; 2176 case 271900: 2177 return TacticalLines.NUC; 2178 case 272000: 2179 return TacticalLines.RAD; 2180 case 290400: 2181 return TacticalLines.CLUSTER; 2182 case 290500: 2183 return TacticalLines.TRIP; 2184 case 282003: 2185 return TacticalLines.OVERHEAD_WIRE; 2186 case 271300: 2187 return TacticalLines.ASLTXING; 2188 case 271500: 2189 return TacticalLines.FORDSITE; 2190 case 271600: 2191 return TacticalLines.FORDIF; 2192 case 290700: 2193 return TacticalLines.FERRY; 2194 case 290800: 2195 return TacticalLines.RAFT; 2196 case 290900: 2197 return TacticalLines.FORTL; 2198 case 291000: 2199 return TacticalLines.FOXHOLE; 2200 case 272100: 2201 return TacticalLines.MSDZ; 2202 case 272200: 2203 return TacticalLines.DRCL; 2204 2205 case 310200: 2206 return TacticalLines.EPW; 2207 case 310300: 2208 return TacticalLines.FARP; 2209 case 310400: 2210 return TacticalLines.RHA; 2211 case 310500: 2212 return TacticalLines.RSA; 2213 case 310600: 2214 return TacticalLines.BSA; 2215 case 310700: 2216 return TacticalLines.DSA; 2217 case 330100: 2218 return TacticalLines.CONVOY; 2219 case 330200: 2220 return TacticalLines.HCONVOY; 2221 case 330300: 2222 return TacticalLines.MSR; 2223 case 330301: 2224 return TacticalLines.MSR_ONEWAY; 2225 case 330401: 2226 return TacticalLines.ASR_ONEWAY; 2227 case 330302: 2228 return TacticalLines.MSR_TWOWAY; 2229 case 330402: 2230 return TacticalLines.ASR_TWOWAY; 2231 case 330303: 2232 return TacticalLines.MSR_ALT; 2233 case 330403: 2234 return TacticalLines.ASR_ALT; 2235 2236 case 330400: 2237 return TacticalLines.ASR; 2238 2239 case 340100: 2240 return TacticalLines.BLOCK; 2241 case 340200: 2242 return TacticalLines.BREACH; 2243 case 340300: 2244 return TacticalLines.BYPASS; 2245 case 340400: 2246 return TacticalLines.CANALIZE; 2247 case 340500: 2248 return TacticalLines.CLEAR; 2249 case 340600: 2250 return TacticalLines.CATK; 2251 case 340700: 2252 return TacticalLines.CATKBYFIRE; 2253 2254 case 340800: 2255 return TacticalLines.DELAY; 2256 case 341000: 2257 return TacticalLines.DISRUPT; 2258 case 341100: 2259 return TacticalLines.FIX; 2260 case 341200: 2261 return TacticalLines.FOLLA; 2262 case 341300: 2263 return TacticalLines.FOLSP; 2264 case 341500: 2265 return TacticalLines.ISOLATE; 2266 case 341700: 2267 return TacticalLines.OCCUPY; 2268 case 341800: 2269 return TacticalLines.PENETRATE; 2270 case 341900: 2271 return TacticalLines.RIP; 2272 case 342000: 2273 return TacticalLines.RETIRE; 2274 case 342100: 2275 return TacticalLines.SECURE; 2276 case 342201: 2277 return TacticalLines.COVER; 2278 case 342202: 2279 return TacticalLines.GUARD; 2280 case 342203: 2281 return TacticalLines.SCREEN; 2282 case 342300: 2283 return TacticalLines.SEIZE; 2284 case 342400: 2285 return TacticalLines.WITHDRAW; 2286 case 342500: 2287 return TacticalLines.WDRAWUP; 2288 case 342600: 2289 return TacticalLines.CORDONKNOCK; 2290 case 342700: 2291 return TacticalLines.CORDONSEARCH; 2292 case 272101: 2293 return TacticalLines.STRIKWARN; 2294 default: 2295 break; 2296 } 2297 return -1; 2298 } 2299 2300 /** 2301 * Some symbol's points are reversed when moving from 2525C to 2525D. This method should be called at the start of each render. 2302 * 2303 * It's a simpler fix to reverse the points order at start than to reverse order when rendering. 2304 * 2305 * Note: Make sure to only call once to not reverse reversed points 2306 * @param tg 2307 */ 2308 private static void reversePointsRevD(TGLight tg) { 2309 try { 2310 if (tg.get_SymbolId().length() < 20 || SymbolID.getSymbolSet(tg.get_SymbolId()) != 25) { 2311 return; 2312 } 2313 switch (tg.get_LineType()) { 2314 case TacticalLines.LC: 2315 case TacticalLines.UNSP: 2316 case TacticalLines.LWFENCE: 2317 case TacticalLines.HWFENCE: 2318 case TacticalLines.SINGLEC: 2319 case TacticalLines.DOUBLEC: 2320 case TacticalLines.TRIPLE: 2321 if (tg.Pixels != null) { 2322 Collections.reverse(tg.Pixels); 2323 } 2324 if (tg.LatLongs != null) { 2325 Collections.reverse(tg.LatLongs); 2326 } 2327 break; 2328 case TacticalLines.CLUSTER: 2329 if (SymbolID.getVersion(tg.get_SymbolId()) < SymbolID.Version_2525E) { 2330 if (tg.Pixels != null) { 2331 Collections.reverse(tg.Pixels); 2332 } 2333 if (tg.LatLongs != null) { 2334 Collections.reverse(tg.LatLongs); 2335 } 2336 } 2337 break; 2338 default: 2339 break; 2340 } 2341 } catch (Exception exc) { 2342 ErrorLogger.LogException("clsRenderer", "reversePointsRevD", 2343 new RendererException("Failed inside reversePointsRevD", exc)); 2344 } 2345 } 2346}