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