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