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