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