001package armyc2.c5isr.JavaTacticalRenderer; 002 003import static armyc2.c5isr.JavaTacticalRenderer.clsUtility.GetLinetypeFromString; 004 005import android.graphics.Bitmap; 006 007import java.util.ArrayList; 008import java.util.HashMap; 009import java.util.Map; 010 011import armyc2.c5isr.JavaLineArray.Channels; 012import armyc2.c5isr.JavaLineArray.POINT2; 013import armyc2.c5isr.JavaLineArray.Shape2; 014import armyc2.c5isr.JavaLineArray.TacticalLines; 015import armyc2.c5isr.JavaLineArray.arraysupport; 016import armyc2.c5isr.JavaLineArray.lineutility; 017import armyc2.c5isr.graphics2d.AffineTransform; 018import armyc2.c5isr.graphics2d.BasicStroke; 019import armyc2.c5isr.graphics2d.BufferedImage; 020import armyc2.c5isr.graphics2d.Font; 021import armyc2.c5isr.graphics2d.FontMetrics; 022import armyc2.c5isr.graphics2d.FontRenderContext; 023import armyc2.c5isr.graphics2d.Graphics2D; 024import armyc2.c5isr.graphics2d.Line2D; 025import armyc2.c5isr.graphics2d.PathIterator; 026import armyc2.c5isr.graphics2d.Point; 027import armyc2.c5isr.graphics2d.Point2D; 028import armyc2.c5isr.graphics2d.Polygon; 029import armyc2.c5isr.graphics2d.Rectangle2D; 030import armyc2.c5isr.graphics2d.Shape; 031import armyc2.c5isr.graphics2d.TextLayout; 032import armyc2.c5isr.renderer.SinglePointRenderer; 033import armyc2.c5isr.renderer.utilities.Color; 034import armyc2.c5isr.renderer.utilities.EntityCode; 035import armyc2.c5isr.renderer.utilities.ErrorLogger; 036import armyc2.c5isr.renderer.utilities.GENCLookup; 037import armyc2.c5isr.renderer.utilities.IPointConversion; 038import armyc2.c5isr.renderer.utilities.ImageInfo; 039import armyc2.c5isr.renderer.utilities.MilStdAttributes; 040import armyc2.c5isr.renderer.utilities.Modifiers; 041import armyc2.c5isr.renderer.utilities.RendererException; 042import armyc2.c5isr.renderer.utilities.RendererSettings; 043import armyc2.c5isr.renderer.utilities.RendererUtilities; 044import armyc2.c5isr.renderer.utilities.ShapeInfo; 045import armyc2.c5isr.renderer.utilities.SymbolID; 046 047/** 048 * This class handles everything having to do with text for a 049 * tactical graphic. Note: labels are handled the same as text modifiers. 050 * 051 */ 052public class Modifier2 { 053 private POINT2[] textPath; 054 private String textID; 055 private String featureID; 056 private String text; 057 058 private Bitmap image; 059 private int iteration; 060 private int justify; 061 private int type; 062 private double lineFactor; 063 private static final String _className = "Modifier2"; 064 @Deprecated 065 private boolean isIntegral = false; 066 private boolean fitsMBR = true; 067 068 Modifier2() { 069 textPath = new POINT2[2]; 070 } 071 072 /** 073 * Put label next to pt0 on opposite side of line 074 */ 075 private static final int toEnd = 1; // Put next to pt0 on opposite side of line 076 /** 077 * put label between both point and apply the angle between the two points 078 */ 079 private static final int aboveMiddle = 2; //use both points 080 /** 081 * one point, label always right-side-up 082 */ 083 private static final int area = 3; //use one point 084 /** 085 * one point, label always right-side-up 086 */ 087 private static final int screen = 4; //use one point, screen, cover, guard points 088 /** 089 * Put next to pt0, but above the line 090 */ 091 private static final int aboveEnd = 5; // Put next to pt0 on line 092 /** 093 * between both points but perpendicular rotation of text 094 */ 095 private static final int aboveMiddlePerpendicular = 6; //use both points 096 /** 097 * For Moving and Halted Convoy. 098 * At start of line behind arrowhead 099 */ 100 private static final int aboveStartInside = 7; //place at the start inside the shape 101 /** 102 * For Moving and Halted Convoy. 103 * At back of line inside arrow shape. 104 */ 105 private static final int aboveEndInside = 8; //place at the end inside the shape 106 /** 107 * Image Modifier, uses one point 108 */ 109 private static final int areaImage = 9; //use one point 110 private static double fillAlphaCanObscureText = 50d; 111 112 private static boolean DoublesBack(POINT2 pt0, POINT2 pt1, POINT2 pt2) { 113 boolean result = true; 114 try { 115 double theta1 = Math.atan2(pt2.y - pt1.y, pt2.x - pt1.x); 116 double theta0 = Math.atan2(pt0.y - pt1.y, pt0.x - pt1.x); 117 double beta = Math.abs(theta0 - theta1); 118 if (beta > 0.1) { 119 result = false; 120 } 121 122 } catch (Exception exc) { 123 ErrorLogger.LogException(_className, "DoublesBack", 124 new RendererException("Failed inside DoublesBack", exc)); 125 } 126 return result; 127 } 128 129 /** 130 * Returns a generic label for the symbol per Mil-Std-2525 131 * 132 * @param tg 133 * @return 134 */ 135 private static String GetCenterLabel(TGLight tg) { 136 String label = ""; 137 try { 138 switch (tg.get_LineType()) { 139 case TacticalLines.SHIP_AOI_RECTANGULAR: 140 case TacticalLines.SHIP_AOI_CIRCULAR: 141 label = "AOI"; 142 break; 143 case TacticalLines.DEFENDED_AREA_RECTANGULAR: 144 case TacticalLines.DEFENDED_AREA_CIRCULAR: 145 label = "DA"; 146 break; 147 case TacticalLines.NOTACK: 148 label = "N"; 149 break; 150 case TacticalLines.LAUNCH_AREA: 151 label = "LA"; 152 break; 153 case TacticalLines.SL: 154 label = "SL"; 155 break; 156 case TacticalLines.TC: 157 label = "TC"; 158 break; 159 case TacticalLines.AARROZ: 160 label = "AARROZ"; 161 break; 162 case TacticalLines.UAROZ: 163 label = "UAROZ"; 164 break; 165 case TacticalLines.WEZ: 166 label = "WEZ"; 167 break; 168 case TacticalLines.FEZ: 169 label = "FEZ"; 170 break; 171 case TacticalLines.JEZ: 172 label = "JEZ"; 173 break; 174 case TacticalLines.IFF_OFF: 175 label = "IFF OFF"; 176 break; 177 case TacticalLines.IFF_ON: 178 label = "IFF ON"; 179 break; 180 case TacticalLines.BCL_REVD: 181 case TacticalLines.BCL: 182 label = "BCL"; 183 break; 184 case TacticalLines.ICL: 185 label = "ICL"; 186 break; 187 case TacticalLines.FEBA: 188 label = "FEBA"; 189 break; 190 case TacticalLines.BDZ: 191 label = "BDZ"; 192 break; 193 case TacticalLines.JTAA: 194 label = "JTAA"; 195 break; 196 case TacticalLines.SAA: 197 label = "SAA"; 198 break; 199 case TacticalLines.SGAA: 200 label = "SGAA"; 201 break; 202 case TacticalLines.ASSAULT: 203 label = "ASLT"; 204 break; 205 case TacticalLines.SAAFR: 206 label = "SAAFR"; 207 break; 208 case TacticalLines.AC: 209 label = "AC"; 210 break; 211 case TacticalLines.SECURE: 212 case TacticalLines.SEIZE: 213 label = "S"; 214 break; 215 case TacticalLines.EVACUATE: 216 label = "E"; 217 break; 218 case TacticalLines.TURN: 219 label = "T"; 220 break; 221 case TacticalLines.RETAIN: 222 label = "R"; 223 break; 224 case TacticalLines.PENETRATE: 225 label = "P"; 226 break; 227 case TacticalLines.OCCUPY: 228 label = "O"; 229 break; 230 case TacticalLines.ISOLATE: 231 label = "I"; 232 break; 233 case TacticalLines.AREA_DEFENSE: 234 label = "AD"; 235 break; 236 case TacticalLines.FIX: 237 label = "F"; 238 break; 239 case TacticalLines.DISRUPT: 240 label = "D"; 241 break; 242 case TacticalLines.CAPTURE: 243 case TacticalLines.CANALIZE: 244 case TacticalLines.CLEAR: 245 case TacticalLines.CONTROL: 246 label = "C"; 247 break; 248 case TacticalLines.BREACH: 249 case TacticalLines.BYPASS: 250 label = "B"; 251 break; 252 case TacticalLines.CORDONKNOCK: 253 label = "C/K"; 254 break; 255 case TacticalLines.CORDONSEARCH: 256 label = "C/S"; 257 break; 258 case TacticalLines.UXO: 259 label = "UXO"; 260 break; 261 case TacticalLines.RETIRE: 262 label = "R"; 263 break; 264 case TacticalLines.PURSUIT: 265 label = "P"; 266 break; 267 case TacticalLines.ENVELOPMENT: 268 label = "E"; 269 break; 270 case TacticalLines.FPOL: 271 label = "P(F)"; 272 break; 273 case TacticalLines.RPOL: 274 label = "P(R)"; 275 break; 276 case TacticalLines.BRDGHD: 277 case TacticalLines.BRDGHD_GE: 278 if (SymbolID.getVersion(tg.get_SymbolId()) >= SymbolID.Version_2525E) 279 label = "BL"; 280 else 281 label = "B"; 282 break; 283 case TacticalLines.HOLD: 284 case TacticalLines.HOLD_GE: 285 //label="HOLDING LINE"; 286 label = "HL"; 287 break; 288 case TacticalLines.PL: 289 label = "PL"; 290 break; 291 case TacticalLines.LL: 292 label = "LL"; 293 break; 294 case TacticalLines.LOCATE: 295 label = "LOC"; 296 break; 297 case TacticalLines.EWL: 298 label = "EWL"; 299 break; 300 case TacticalLines.SCREEN: 301 label = "S"; 302 break; 303 case TacticalLines.COVER: 304 label = "C"; 305 break; 306 case TacticalLines.GUARD: 307 label = "G"; 308 break; 309 case TacticalLines.RIP: 310 label = "RIP"; 311 break; 312 case TacticalLines.MOBILE_DEFENSE: 313 label = "MD"; 314 break; 315 case TacticalLines.DEMONSTRATE: 316 label = "DEM"; 317 break; 318 case TacticalLines.WITHDRAW: 319 label = "W"; 320 break; 321 case TacticalLines.DISENGAGE: 322 label = "DIS"; 323 break; 324 case TacticalLines.WDRAWUP: 325 label = "WP"; 326 break; 327 case TacticalLines.CATK: 328 case TacticalLines.CATKBYFIRE: 329 label = "CATK"; 330 break; 331 case TacticalLines.FLOT: 332 label = "FLOT"; 333 break; 334 case TacticalLines.LC: 335 label = "LC"; 336 break; 337 case TacticalLines.ASSY: 338 label = "AA"; 339 break; 340 case TacticalLines.EA: 341 label = "EA"; 342 break; 343 case TacticalLines.DZ: 344 label = "DZ"; 345 break; 346 case TacticalLines.EZ: 347 label = "EZ"; 348 break; 349 case TacticalLines.LZ: 350 label = "LZ"; 351 break; 352 case TacticalLines.LAA: 353 label = "LAA"; 354 break; 355 case TacticalLines.PZ: 356 label = "PZ"; 357 break; 358 case TacticalLines.MRR: 359 label = "MRR"; 360 break; 361 case TacticalLines.SC: 362 label = "SC"; 363 break; 364 case TacticalLines.LLTR: 365 label = "LLTR"; 366 break; 367 case TacticalLines.ROZ: 368 label = "ROZ"; 369 break; 370 case TacticalLines.FAADZ: 371 label = "SHORADEZ"; 372 break; 373 case TacticalLines.HIDACZ: 374 label = "HIDACZ"; 375 break; 376 case TacticalLines.MEZ: 377 label = "MEZ"; 378 break; 379 case TacticalLines.LOMEZ: 380 label = "LOMEZ"; 381 break; 382 case TacticalLines.HIMEZ: 383 label = "HIMEZ"; 384 break; 385 case TacticalLines.WFZ_REVD: 386 case TacticalLines.WFZ: 387 label = "WFZ"; 388 break; 389 case TacticalLines.MINED: 390 case TacticalLines.FENCED: 391 label = "M"; 392 break; 393 case TacticalLines.PNO: 394 label = "(P)"; 395 break; 396 case TacticalLines.OBJ: 397 label = "OBJ"; 398 break; 399 case TacticalLines.NAI: 400 label = "NAI"; 401 break; 402 case TacticalLines.TAI: 403 label = "TAI"; 404 break; 405 case TacticalLines.BASE_CAMP_REVD: 406 case TacticalLines.BASE_CAMP: 407 label = "BC"; 408 break; 409 case TacticalLines.GUERILLA_BASE_REVD: 410 case TacticalLines.GUERILLA_BASE: 411 label = "GB"; 412 break; 413 case TacticalLines.LINTGTS: 414 label = "SMOKE"; 415 break; 416 case TacticalLines.FPF: 417 label = "FPF"; 418 break; 419 case TacticalLines.ATKPOS: 420 label = "ATK"; 421 break; 422 case TacticalLines.FCL: 423 label = "FCL"; 424 break; 425 case TacticalLines.LOA: 426 label = "LOA"; 427 break; 428 case TacticalLines.LOD: 429 label = "LD"; 430 break; 431 case TacticalLines.PLD: 432 label = "PLD"; 433 break; 434 case TacticalLines.DELAY: 435 case TacticalLines.DENY: 436 label = "D"; 437 break; 438 case TacticalLines.RELEASE: 439 label = "RL"; 440 break; 441 case TacticalLines.HOL: 442 label = "HOL"; 443 break; 444 case TacticalLines.BHL: 445 label = "BHL"; 446 break; 447 case TacticalLines.SMOKE: 448 label = "SMOKE"; 449 break; 450 case TacticalLines.NFL: 451 label = "NFL"; 452 break; 453 case TacticalLines.MFP: 454 label = "MFP"; 455 break; 456 case TacticalLines.FSCL: 457 label = "FSCL"; 458 break; 459 case TacticalLines.CFL: 460 label = "CFL"; 461 break; 462 case TacticalLines.RFL: 463 label = "RFL"; 464 break; 465 case TacticalLines.AO: 466 label = "AO"; 467 break; 468 case TacticalLines.BOMB: 469 label = "BOMB"; 470 break; 471 case TacticalLines.TGMF: 472 label = "TGMF"; 473 break; 474 case TacticalLines.FSA: 475 label = "FSA"; 476 break; 477 case TacticalLines.FSA_CIRCULAR: 478 case TacticalLines.FSA_RECTANGULAR: 479 label = "FSA"; 480 break; 481 case TacticalLines.ACA: 482 case TacticalLines.ACA_CIRCULAR: 483 case TacticalLines.ACA_RECTANGULAR: 484 label = "ACA"; 485 break; 486 case TacticalLines.FFA: 487 case TacticalLines.FFA_CIRCULAR: 488 case TacticalLines.FFA_RECTANGULAR: 489 label = "FFA"; 490 break; 491 case TacticalLines.NFA: 492 case TacticalLines.NFA_CIRCULAR: 493 case TacticalLines.NFA_RECTANGULAR: 494 label = "NFA"; 495 break; 496 case TacticalLines.RFA: 497 case TacticalLines.RFA_CIRCULAR: 498 case TacticalLines.RFA_RECTANGULAR: 499 label = "RFA"; 500 break; 501 case TacticalLines.ATI: 502 case TacticalLines.ATI_CIRCULAR: 503 case TacticalLines.ATI_RECTANGULAR: 504 if (SymbolID.getVersion(tg.get_SymbolId()) >= SymbolID.Version_2525Ech1) 505 label = "ATIZ"; 506 else 507 label = "ATI ZONE"; 508 break; 509 case TacticalLines.PAA: 510 case TacticalLines.PAA_CIRCULAR: 511 case TacticalLines.PAA_RECTANGULAR: 512 label = "PAA"; 513 break; 514 case TacticalLines.CFFZ: 515 case TacticalLines.CFFZ_CIRCULAR: 516 case TacticalLines.CFFZ_RECTANGULAR: 517 label = "CFF ZONE"; 518 break; 519 case TacticalLines.CFZ: 520 case TacticalLines.CFZ_CIRCULAR: 521 case TacticalLines.CFZ_RECTANGULAR: 522 label = "CF ZONE"; 523 break; 524 case TacticalLines.SENSOR: 525 case TacticalLines.SENSOR_CIRCULAR: 526 case TacticalLines.SENSOR_RECTANGULAR: 527 label = "SENSOR ZONE"; 528 break; 529 case TacticalLines.CENSOR: 530 case TacticalLines.CENSOR_CIRCULAR: 531 case TacticalLines.CENSOR_RECTANGULAR: 532 label = "CENSOR ZONE"; 533 break; 534 case TacticalLines.DA: 535 case TacticalLines.DA_CIRCULAR: 536 case TacticalLines.DA_RECTANGULAR: 537 label = "DA"; 538 break; 539 case TacticalLines.ZOR: 540 case TacticalLines.ZOR_CIRCULAR: 541 case TacticalLines.ZOR_RECTANGULAR: 542 label = "ZOR"; 543 break; 544 case TacticalLines.TBA: 545 case TacticalLines.TBA_CIRCULAR: 546 case TacticalLines.TBA_RECTANGULAR: 547 label = "TBA"; 548 break; 549 case TacticalLines.TVAR: 550 case TacticalLines.TVAR_CIRCULAR: 551 case TacticalLines.TVAR_RECTANGULAR: 552 label = "TVAR"; 553 break; 554 case TacticalLines.KILLBOXBLUE: 555 case TacticalLines.KILLBOXBLUE_CIRCULAR: 556 case TacticalLines.KILLBOXBLUE_RECTANGULAR: 557 label = "BKB"; 558 break; 559 case TacticalLines.KILLBOXPURPLE: 560 case TacticalLines.KILLBOXPURPLE_CIRCULAR: 561 case TacticalLines.KILLBOXPURPLE_RECTANGULAR: 562 label = "PKB"; 563 break; 564 case TacticalLines.MSR: 565 case TacticalLines.MSR_ONEWAY: 566 case TacticalLines.MSR_TWOWAY: 567 case TacticalLines.MSR_ALT: 568 label = "MSR"; 569 break; 570 case TacticalLines.ASR: 571 case TacticalLines.ASR_ONEWAY: 572 case TacticalLines.ASR_TWOWAY: 573 case TacticalLines.ASR_ALT: 574 label = "ASR"; 575 break; 576 case TacticalLines.TRAFFIC_ROUTE: 577 case TacticalLines.TRAFFIC_ROUTE_ONEWAY: 578 case TacticalLines.TRAFFIC_ROUTE_ALT: 579 label = "ROUTE"; 580 break; 581 case TacticalLines.LDLC: 582 label = "LD/LC"; 583 break; 584 case TacticalLines.AIRHEAD: 585 label = "AIRHEAD LINE"; 586 break; 587 case TacticalLines.BLOCK: 588 case TacticalLines.BEARING: 589 label = "B"; 590 break; 591 case TacticalLines.BEARING_J: 592 label = "J"; 593 break; 594 case TacticalLines.BEARING_RDF: 595 label = "RDF"; 596 break; 597 case TacticalLines.ELECTRO: 598 case TacticalLines.ESCORT: 599 label = "E"; 600 break; 601 case TacticalLines.BEARING_EW: 602 label = "EW"; 603 break; 604 case TacticalLines.ACOUSTIC: 605 case TacticalLines.ACOUSTIC_AMB: 606 label = "A"; 607 break; 608 case TacticalLines.TORPEDO: 609 label = "T"; 610 break; 611 case TacticalLines.OPTICAL: 612 label = "O"; 613 break; 614 case TacticalLines.DHA: 615 label = "DHA"; 616 break; 617 case TacticalLines.KILL_ZONE: 618 label = "KILL ZONE"; 619 break; 620 case TacticalLines.FARP: 621 label = "FARP"; 622 break; 623 case TacticalLines.BSA: 624 label = "BSA"; 625 break; 626 case TacticalLines.DSA: 627 label = "DSA"; 628 break; 629 case TacticalLines.CSA: 630 label = "CSA"; 631 break; 632 case TacticalLines.RSA: 633 label = "RSA"; 634 break; 635 case TacticalLines.CONTAIN: 636 label = "C"; 637 break; 638 case TacticalLines.OBSFAREA: 639 label = "FREE"; 640 break; 641 case TacticalLines.TRIP: 642 label = "t"; 643 break; 644 case TacticalLines.EXFILTRATION: 645 label = "EX"; 646 break; 647 case TacticalLines.INFILTRATION: 648 label = "IN"; 649 break; 650 default: 651 break; 652 } 653 } catch (Exception exc) { 654 //clsUtility.WriteFile("Error in Modifier2.GetCenterLabel"); 655 ErrorLogger.LogException(_className, "GetCenterLabel", 656 new RendererException("Failed inside GetCenterLabel", exc)); 657 } 658 return label; 659 } 660 //non CPOF clients using best fit need these accessors 661 662 public POINT2[] get_TextPath() { 663 return textPath; 664 } 665 666 protected void set_TextPath(POINT2[] value) { 667 textPath = value; 668 } 669 670 @Deprecated 671 protected void set_IsIntegral(boolean value) { 672 isIntegral = value; 673 } 674 675 @Deprecated 676 protected boolean get_IsIntegral() { 677 return isIntegral; 678 } 679 680 private static void AddOffsetModifier(TGLight tg, 681 String text, 682 int type, 683 double lineFactor, 684 int startIndex, 685 int endIndex, 686 double spaces, 687 String rightOrLeft) { 688 if (rightOrLeft == null || tg.Pixels == null || tg.Pixels.size() < 2 || endIndex >= tg.Pixels.size()) { 689 return; 690 } 691 692 POINT2 pt0 = tg.Pixels.get(startIndex); 693 POINT2 pt1 = tg.Pixels.get(endIndex); 694 if (rightOrLeft.equals("left")) { 695 pt0.x -= spaces; 696 pt1.x -= spaces; 697 } else { 698 pt0.x += spaces; 699 pt1.x += spaces; 700 } 701 AddModifier2(tg, text, type, lineFactor, pt0, pt1, false); 702 } 703 704 /** 705 * 706 * @param tg 707 * @param text 708 * @param type 709 * @param lineFactor 710 * @param ptStart 711 * @param ptEnd 712 */ 713 private static void AddModifier(TGLight tg, 714 String text, 715 int type, 716 double lineFactor, 717 POINT2 ptStart, 718 POINT2 ptEnd) { 719 if (tg.Pixels == null || tg.Pixels.size() < 2) { 720 return; 721 } 722 AddModifier2(tg, text, type, lineFactor, ptStart, ptEnd, false); 723 } 724 725 private static void AddModifier2(TGLight tg, 726 String text, 727 int type, 728 double lineFactor, 729 POINT2 pt0, 730 POINT2 pt1, 731 boolean isIntegral) { 732 AddModifier2(tg, text, type, lineFactor, pt0, pt1, isIntegral, null); 733 } 734 735 private static void AddModifier2(TGLight tg, 736 String text, 737 int type, 738 double lineFactor, 739 POINT2 pt0, 740 POINT2 pt1, 741 boolean isIntegral, 742 String modifierType) { 743 try { 744 if (text == null || text.equals("")) { 745 return; 746 } 747 748 Modifier2 modifier = new Modifier2(); 749 modifier.set_IsIntegral(isIntegral); 750 modifier.text = text; 751 modifier.type = type; 752 modifier.lineFactor = lineFactor; 753 modifier.textPath[0] = pt0; 754 modifier.textPath[1] = pt1; 755 modifier.textID = modifierType; 756 tg.modifiers.add(modifier); 757 } catch (Exception exc) { 758 ErrorLogger.LogException(_className, "AddModifier", 759 new RendererException("Failed inside AddModifier", exc)); 760 } 761 } 762 763 private static void AddIntegralModifier(TGLight tg, 764 String text, 765 int type, 766 double lineFactor, 767 int startIndex, 768 int endIndex) { 769 AddIntegralModifier(tg, text, type, lineFactor, startIndex, endIndex, true); 770 } 771 772 private static void AddIntegralModifier(TGLight tg, 773 String text, 774 int type, 775 double lineFactor, 776 int startIndex, 777 int endIndex, 778 Boolean isIntegral) { 779 AddIntegralModifier(tg, text, type, lineFactor, startIndex, endIndex, isIntegral, null); 780 } 781 782 private static void AddIntegralModifier(TGLight tg, 783 String text, 784 int type, 785 double lineFactor, 786 int startIndex, 787 int endIndex, 788 Boolean isIntegral, 789 String modifierType) { 790 if (tg.Pixels == null || tg.Pixels.isEmpty() || endIndex >= tg.Pixels.size()) { 791 return; 792 } 793 AddIntegralAreaModifier(tg, text, type, lineFactor, tg.Pixels.get(startIndex), tg.Pixels.get(endIndex), isIntegral, modifierType); 794 } 795 796 /** 797 * Creates and adds center modifiers for generic areas 798 * 799 * @param tg 800 * @param text 801 * @param type 802 * @param lineFactor 803 * @param pt0 804 * @param pt1 805 */ 806 private static void AddAreaModifier(TGLight tg, 807 String text, 808 int type, 809 double lineFactor, 810 POINT2 pt0, 811 POINT2 pt1) { 812 AddIntegralAreaModifier(tg, text, type, lineFactor, pt0, pt1, true); 813 } 814 815 /** 816 * sets modifier.textId to the modifier type, e.g. label, T, T1, etc. 817 * 818 * @param tg 819 * @param text 820 * @param type 821 * @param lineFactor 822 * @param pt0 823 * @param pt1 824 * @param modifierType 825 */ 826 private static void AddAreaModifier(TGLight tg, 827 String text, 828 int type, 829 double lineFactor, 830 POINT2 pt0, 831 POINT2 pt1, 832 String modifierType) { 833 AddIntegralAreaModifier(tg, text, type, lineFactor, pt0, pt1, true, modifierType); 834 } 835 836 private static void AddIntegralAreaModifier(TGLight tg, 837 String text, 838 int type, 839 double lineFactor, 840 POINT2 pt0, 841 POINT2 pt1, 842 Boolean isIntegral) { 843 AddIntegralAreaModifier(tg,text,type,lineFactor,pt0, pt1, isIntegral, null); 844 } 845 846 private static void AddIntegralAreaModifier(TGLight tg, 847 Bitmap image, 848 int type, 849 double lineFactor, 850 POINT2 pt0, 851 POINT2 pt1, 852 Boolean isIntegral) { 853 try { 854 if (image == null || image.equals("")) { 855 return; 856 } 857 858 Modifier2 modifier = new Modifier2(); 859 modifier.set_IsIntegral(isIntegral); 860 modifier.image = image; 861 if (image == null || image.equals("")) { 862 return; 863 } 864 865 if (pt0 == null || pt1 == null) { 866 return; 867 } 868 869 modifier.type = type; 870 modifier.lineFactor = lineFactor; 871 modifier.textPath[0] = pt0; 872 modifier.textPath[1] = pt1; 873 tg.modifiers.add(modifier); 874 } catch (Exception exc) { 875 ErrorLogger.LogException(_className, "AddAreaModifier", 876 new RendererException("Failed inside AddAreaModifier", exc)); 877 } 878 } 879 880 private static void AddIntegralAreaModifier(TGLight tg, 881 String text, 882 int type, 883 double lineFactor, 884 POINT2 pt0, 885 POINT2 pt1, 886 Boolean isIntegral, 887 String modifierType) { 888 if (pt0 == null || pt1 == null) { 889 return; 890 } 891 AddModifier2(tg, text, type, lineFactor, pt0, pt1, isIntegral, modifierType); 892 } 893 894 /** 895 * Returns symbol MBR. Assumes points have been initialized with value of 896 * 0th point 897 * 898 * @param tg the tactical graphic object 899 * @param ptUl OUT - MBR upper left 900 * @param ptUr OUT - MBR upper right 901 * @param ptLr OUT - MBR lower right 902 * @param ptLl OUT - MBR lower left 903 */ 904 public static void GetMBR(TGLight tg, 905 POINT2 ptUl, 906 POINT2 ptUr, 907 POINT2 ptLr, 908 POINT2 ptLl) { 909 try { 910 int j = 0; 911 double x = 0; 912 double y = 0; 913 ptUl.x = tg.Pixels.get(0).x; 914 ptUl.y = tg.Pixels.get(0).y; 915 ptUr.x = tg.Pixels.get(0).x; 916 ptUr.y = tg.Pixels.get(0).y; 917 ptLl.x = tg.Pixels.get(0).x; 918 ptLl.y = tg.Pixels.get(0).y; 919 ptLr.x = tg.Pixels.get(0).x; 920 ptLr.y = tg.Pixels.get(0).y; 921 int n = tg.Pixels.size(); 922 //for (j = 1; j < tg.Pixels.size(); j++) 923 for (j = 1; j < n; j++) { 924 x = tg.Pixels.get(j).x; 925 y = tg.Pixels.get(j).y; 926 if (x < ptLl.x) { 927 ptLl.x = x; 928 ptUl.x = x; 929 } 930 if (x > ptLr.x) { 931 ptLr.x = x; 932 ptUr.x = x; 933 } 934 if (y > ptLl.y) { 935 ptLl.y = y; 936 ptLr.y = y; 937 } 938 if (y < ptUl.y) { 939 ptUl.y = y; 940 ptUr.y = y; 941 } 942 } 943 } catch (Exception exc) { 944 ErrorLogger.LogException(_className, "GetMBR", 945 new RendererException("Failed inside GetMBR", exc)); 946 } 947 } 948 949 /** 950 * Tests segment of a Boundary 951 * 952 * @param tg 953 * @param g2d 954 * @param middleSegment 955 * @return 956 */ 957 private static boolean GetBoundarySegmentTooShort(TGLight tg, 958 Graphics2D g2d, 959 int middleSegment) { 960 boolean lineTooShort = false; 961 try { 962 //int middleSegment = tg.Pixels.size() / 2 - 1; 963 g2d.setFont(tg.get_Font()); 964 FontMetrics metrics = g2d.getFontMetrics(); 965 String echelonSymbol = null; 966 int stringWidthEchelonSymbol = 0; 967 968 POINT2 pt0 = tg.Pixels.get(middleSegment); 969 POINT2 pt1 = tg.Pixels.get(middleSegment + 1); 970 double dist = lineutility.CalcDistanceDouble(pt0, pt1); 971 972 echelonSymbol = tg.get_EchelonSymbol(); 973 974 if (echelonSymbol != null) { 975 stringWidthEchelonSymbol = metrics.stringWidth(echelonSymbol); 976 } 977 978 int tWidth = 0, t1Width = 0; 979 if (tg.get_Name() != null && !tg.get_Name().isEmpty()) { 980 tWidth = metrics.stringWidth(tg.get_Name()); 981 } 982 if (tg.get_T1() != null && !tg.get_T1().isEmpty()) { 983 t1Width = metrics.stringWidth(tg.get_T1()); 984 } 985 986 int totalWidth = stringWidthEchelonSymbol; 987 if (totalWidth < tWidth) { 988 totalWidth = tWidth; 989 } 990 if (totalWidth < t1Width) { 991 totalWidth = t1Width; 992 } 993 994 switch (tg.get_LineType()) { 995 case TacticalLines.BOUNDARY: 996 if (dist < 1.25 * (totalWidth)) { 997 lineTooShort = true; 998 } 999 break; 1000 default: 1001 break; 1002 } 1003 } catch (Exception exc) { 1004 ErrorLogger.LogException(_className, "GetBoundaryLineTooShort", 1005 new RendererException("Failed inside GetBoundaryLineTooShort", exc)); 1006 } 1007 return lineTooShort; 1008 } 1009 1010 /** 1011 * Handles the line breaks for Boundary and Engineer Work Line 1012 * 1013 * @param tg 1014 * @param g2d 1015 */ 1016 private static void AddBoundaryModifiers(TGLight tg, 1017 Graphics2D g2d, 1018 Object clipBounds) { 1019 try { 1020 int j = 0; 1021 double csFactor = 1d; 1022 Boolean foundSegment = false; 1023 POINT2 pt0 = null, pt1 = null, ptLast = null; 1024 double TLineFactor = 0, T1LineFactor = 0; 1025 Boolean lineTooShort = false; 1026 String countryCode = ""; 1027 if(!tg.get_AS().equals("")) { 1028 countryCode = " (" + tg.get_AS() + ")"; 1029 } 1030 if (tg.get_Client().equals("cpof3d")) { 1031 csFactor = 0.85d; 1032 } 1033 1034 int middleSegment = getVisibleMiddleSegment(tg, clipBounds); 1035 //for (j = 0; j < tg.Pixels.size() - 1; j++) { 1036 for (j = middleSegment; j == middleSegment; j++) { 1037 /* if (tg.get_Client().equalsIgnoreCase("ge")) { 1038 if (j != middleSegment) { 1039 continue; 1040 } 1041 }*/ 1042 1043 pt0 = tg.Pixels.get(j); 1044 pt1 = tg.Pixels.get(j + 1); 1045 if (pt0.x < pt1.x) { 1046 TLineFactor = -1.3; 1047 T1LineFactor = 1; 1048 } else if (pt0.x == pt1.x) { 1049 if (pt1.y < pt0.y) { 1050 TLineFactor = -1; 1051 T1LineFactor = 1; 1052 } else { 1053 TLineFactor = 1; 1054 T1LineFactor = -1; 1055 } 1056 } else { 1057 TLineFactor = 1; 1058 T1LineFactor = -1.3; 1059 } 1060 //is the segment too short? 1061 lineTooShort = GetBoundarySegmentTooShort(tg, g2d, j); 1062 1063 if (lineTooShort == false) { 1064 foundSegment = true; 1065 AddIntegralModifier(tg, tg.get_Name() + countryCode, aboveMiddle, TLineFactor * csFactor, j, j + 1, true); 1066 //the echelon symbol 1067 if (tg.get_EchelonSymbol() != null && !tg.get_EchelonSymbol().equals("")) { 1068 AddIntegralModifier(tg, tg.get_EchelonSymbol(), aboveMiddle, -0.20 * csFactor, j, j + 1, true); 1069 } 1070 //the T1 modifier 1071 AddIntegralModifier(tg, tg.get_T1(), aboveMiddle, T1LineFactor * csFactor, j, j + 1, true); 1072 } 1073 }//end for loop 1074 if (foundSegment == false) { 1075 pt0 = new POINT2(); 1076 pt1 = new POINT2(); 1077 // Get boundary middle segment 1078 final String echelonSymbol = tg.get_EchelonSymbol(); 1079 final FontMetrics metrics = g2d.getFontMetrics(); 1080 double modDist = 0; 1081 1082 if (echelonSymbol != null) { 1083 modDist = 1.5 * metrics.stringWidth(echelonSymbol); 1084 } 1085 1086 final double segDist = lineutility.CalcDistanceDouble(tg.Pixels.get(middleSegment), tg.Pixels.get(middleSegment + 1)); 1087 1088 g2d.setFont(tg.get_Font()); 1089 POINT2 midpt = lineutility.MidPointDouble(tg.Pixels.get(middleSegment), tg.Pixels.get(middleSegment + 1), 0); 1090 POINT2 ptTemp = null; 1091 if (segDist < modDist) { 1092 ptTemp = lineutility.ExtendAlongLineDouble(midpt, tg.Pixels.get(middleSegment), modDist / 2); 1093 pt0.x = ptTemp.x; 1094 pt0.y = ptTemp.y; 1095 ptTemp = lineutility.ExtendAlongLineDouble(midpt, tg.Pixels.get(middleSegment + 1), modDist / 2); 1096 } else { 1097 ptTemp = tg.Pixels.get(middleSegment); 1098 pt0.x = ptTemp.x; 1099 pt0.y = ptTemp.y; 1100 ptTemp = tg.Pixels.get(middleSegment + 1); 1101 } 1102 pt1.x = ptTemp.x; 1103 pt1.y = ptTemp.y; 1104 1105 AddIntegralModifier(tg, tg.get_Name() + countryCode, aboveMiddle, TLineFactor * csFactor, middleSegment, middleSegment + 1, true); 1106 //the echelon symbol 1107 if (echelonSymbol != null && !echelonSymbol.equals("")) { 1108 AddIntegralModifier(tg, echelonSymbol, aboveMiddle, -0.2020 * csFactor, middleSegment, middleSegment + 1, true); 1109 } 1110 //the T1 modifier 1111 AddIntegralModifier(tg, tg.get_T1(), aboveMiddle, T1LineFactor * csFactor, middleSegment, middleSegment + 1, true); 1112 }//end if foundSegment==false 1113 } catch (Exception exc) { 1114 ErrorLogger.LogException(_className, "AddBoundaryModifiers", 1115 new RendererException("Failed inside AddBoundaryModifiers", exc)); 1116 } 1117 } 1118 1119 /** 1120 * added for USAS 1121 * 1122 * @param tg 1123 * @param metrics 1124 * @deprecated 1125 */ 1126 private static void AddNameAboveDTG(TGLight tg, FontMetrics metrics) { 1127 try { 1128 double csFactor = 1; 1129 if (tg.get_Client().equals("cpof3d")) { 1130 csFactor = 0.667; 1131 } 1132 String label = GetCenterLabel(tg); 1133 POINT2 pt0 = new POINT2(tg.Pixels.get(0)); 1134 POINT2 pt1 = new POINT2(tg.Pixels.get(1)); 1135 int lastIndex = tg.Pixels.size() - 1; 1136 int nextToLastIndex = tg.Pixels.size() - 2; 1137 POINT2 ptLast = new POINT2(tg.Pixels.get(lastIndex)); 1138 POINT2 ptNextToLast = new POINT2(tg.Pixels.get(nextToLastIndex)); 1139 shiftModifierPath(tg, pt0, pt1, ptLast, ptNextToLast); 1140 double stringWidth = metrics.stringWidth(label + " " + tg.get_Name()); 1141 AddIntegralAreaModifier(tg, label + " " + tg.get_Name(), toEnd, 0, pt0, pt1, false); 1142 pt1 = lineutility.ExtendAlongLineDouble(tg.Pixels.get(0), tg.Pixels.get(1), -1.5 * stringWidth); 1143 AddModifier2(tg, tg.get_DTG(), aboveMiddle, 0.7 * csFactor, pt0, pt1, false); 1144 AddModifier2(tg, tg.get_DTG1(), aboveMiddle, 1.7 * csFactor, pt0, pt1, false); 1145 AddIntegralAreaModifier(tg, label + " " + tg.get_Name(), toEnd, 0, ptLast, ptNextToLast, false); 1146 pt0 = tg.Pixels.get(lastIndex); 1147 pt1 = lineutility.ExtendAlongLineDouble(tg.Pixels.get(lastIndex), tg.Pixels.get(nextToLastIndex), -1.5 * stringWidth); 1148 AddModifier2(tg, tg.get_DTG(), aboveMiddle, 0.7 * csFactor, pt0, pt1, false); 1149 AddModifier2(tg, tg.get_DTG1(), aboveMiddle, 1.7 * csFactor, pt0, pt1, false); 1150 } catch (Exception exc) { 1151 ErrorLogger.LogException(_className, "AddNameAboveDTG", 1152 new RendererException("Failed inside AddNameAboveDTG", exc)); 1153 } 1154 } 1155 1156 /** 1157 * shifts the path for modifiers that use toEnd to prevent vertical paths 1158 * 1159 * @param tg 1160 * @param pt0 1161 * @param pt1 1162 * @param ptLast 1163 * @param ptNextToLast 1164 */ 1165 private static void shiftModifierPath(TGLight tg, 1166 POINT2 pt0, 1167 POINT2 pt1, 1168 POINT2 ptLast, 1169 POINT2 ptNextToLast) { 1170 try { 1171 POINT2 p0 = null, p1 = null; 1172 double last = -1.0; 1173 switch (tg.get_LineType()) { 1174 case TacticalLines.BOUNDARY: 1175 for (int j = 0; j < tg.Pixels.size() - 1; j++) { 1176 p0 = tg.Pixels.get(j); 1177 p1 = tg.Pixels.get(j + 1); 1178 //if(p0.x==p1.x) 1179 if (Math.abs(p0.x - p1.x) < 1) { 1180 p1.x += last; 1181 last = -last; 1182 } 1183 } 1184 break; 1185 case TacticalLines.PDF: 1186 case TacticalLines.PL: 1187 case TacticalLines.DECISION_LINE: 1188 case TacticalLines.FEBA: 1189 case TacticalLines.LOA: 1190 case TacticalLines.LOD: 1191 case TacticalLines.RELEASE: 1192 case TacticalLines.HOL: 1193 case TacticalLines.BHL: 1194 case TacticalLines.LDLC: 1195 case TacticalLines.LL: 1196 case TacticalLines.EWL: 1197 case TacticalLines.FCL: 1198 case TacticalLines.PLD: 1199 case TacticalLines.NFL: 1200 case TacticalLines.FLOT: 1201 case TacticalLines.LC: 1202 case TacticalLines.HOLD: 1203 case TacticalLines.BRDGHD: 1204 case TacticalLines.HOLD_GE: 1205 case TacticalLines.BRDGHD_GE: 1206 //if (pt0 != null && pt1 != null && pt0.x == pt1.x) 1207 if (pt0 != null && pt1 != null && Math.abs(pt0.x - pt1.x) < 1) { 1208 pt1.x += 1; 1209 } 1210 //if (ptLast != null && ptNextToLast != null && ptNextToLast.x == ptLast.x) 1211 if (ptLast != null && ptNextToLast != null && Math.abs(ptNextToLast.x - ptLast.x) < 1) { 1212 ptNextToLast.x += 1; 1213 } 1214 break; 1215 default: 1216 return; 1217 } 1218 } catch (Exception exc) { 1219 ErrorLogger.LogException(_className, "shiftModifierPath", 1220 new RendererException("Failed inside shiftModifierPath", exc)); 1221 } 1222 } 1223 1224 /** 1225 * Adds two or four labels on area outline 1226 * 1227 * @param label 1228 * @param tg 1229 * @param twoLabelOnly - when true only two labels are added to line (east and west most segment midpoints) 1230 * when false, four labels are added to line (north, south, east and west most segment midpoints) 1231 */ 1232 private static void addModifierOnLine(String label, TGLight tg, boolean twoLabelOnly) { 1233 if (label == null || label.isEmpty() || tg.Pixels.isEmpty()) { 1234 return; 1235 } 1236 try { 1237 POINT2 leftPt = lineutility.MidPointDouble(tg.Pixels.get(0), tg.Pixels.get(1), 0); 1238 POINT2 rightPt = lineutility.MidPointDouble(tg.Pixels.get(0), tg.Pixels.get(1), 0); 1239 POINT2 topPt = lineutility.MidPointDouble(tg.Pixels.get(0), tg.Pixels.get(1), 0); 1240 POINT2 bottomPt = lineutility.MidPointDouble(tg.Pixels.get(0), tg.Pixels.get(1), 0); 1241 for (int j = 1; j < tg.Pixels.size() - 1; j++) { 1242 POINT2 midPt = lineutility.MidPointDouble(tg.Pixels.get(j), tg.Pixels.get(j + 1), 0); 1243 if (midPt.x <= leftPt.x) { 1244 leftPt = midPt; 1245 } 1246 if (midPt.x >= rightPt.x) { 1247 rightPt = midPt; 1248 } 1249 if (midPt.y <= topPt.y) { 1250 topPt = midPt; 1251 } 1252 if (midPt.y >= bottomPt.y) { 1253 bottomPt = midPt; 1254 } 1255 } 1256 1257 if (leftPt != rightPt) 1258 AddAreaModifier(tg, label, aboveMiddle, 0, leftPt, leftPt); 1259 AddAreaModifier(tg, label, aboveMiddle, 0, rightPt, rightPt); 1260 if (!twoLabelOnly) { 1261 if (bottomPt != leftPt && bottomPt != rightPt) 1262 AddAreaModifier(tg, label, aboveMiddle, 0, bottomPt, bottomPt); 1263 if (topPt != leftPt && topPt != rightPt && topPt != bottomPt) 1264 AddAreaModifier(tg, label, aboveMiddle, 0, topPt, topPt); 1265 } 1266 } catch (Exception exc) { 1267 ErrorLogger.LogException(_className, "addModifierOnLine", 1268 new RendererException("Failed inside addModifierOnLine", exc)); 1269 } 1270 } 1271 1272 private static void addModifierOnLine(String label, TGLight tg) { 1273 addModifierOnLine(label, tg, false); 1274 } 1275 1276 /** 1277 * Adds N modifier on area outline 1278 */ 1279 private static void addNModifier(TGLight tg) { 1280 if (tg.isHostile()) { 1281 addModifierOnLine(tg.get_N(), tg, true); 1282 } 1283 } 1284 1285 private static void addModifierBottomSegment(TGLight tg, String text) { 1286 int index = 0; 1287 double y = tg.Pixels.get(index).y + tg.Pixels.get(index + 1).y; 1288 for (int i = 1; i < tg.Pixels.size() - 1; i++) { 1289 if (tg.Pixels.get(i).y + tg.Pixels.get(i + 1).y > y) { 1290 index = i; 1291 y = tg.Pixels.get(index).y + tg.Pixels.get(index + 1).y; 1292 } 1293 } 1294 AddIntegralModifier(tg, text, aboveMiddle, 0, index, index + 1, false); 1295 } 1296 1297 private static void addModifierTopSegment(TGLight tg, String text) { 1298 int index = 0; 1299 double y = tg.Pixels.get(index).y + tg.Pixels.get(index + 1).y; 1300 for (int i = 1; i < tg.Pixels.size() - 1; i++) { 1301 if (tg.Pixels.get(i).y + tg.Pixels.get(i + 1).y < y) { 1302 index = i; 1303 y = tg.Pixels.get(index).y + tg.Pixels.get(index + 1).y; 1304 } 1305 } 1306 AddIntegralModifier(tg, text, aboveMiddle, 0, index, index + 1, false); 1307 } 1308 1309 private static void addDTG(TGLight tg, int type, double lineFactor1, double lineFactor2, POINT2 pt0, POINT2 pt1, FontMetrics metrics) { 1310 if (pt0 == null || pt1 == null) 1311 return; 1312 1313 double maxDTGWidth; 1314 if (pt0.x == pt1.x && pt0.y == pt1.y) { 1315 POINT2 ptUl = new POINT2(), ptUr = new POINT2(), ptLr = new POINT2(), ptLl = new POINT2(); 1316 GetMBR(tg, ptUl, ptUr, ptLr, ptLl); 1317 maxDTGWidth = lineutility.CalcDistanceDouble(ptUl, ptUr); 1318 } else { 1319 maxDTGWidth = lineutility.CalcDistanceDouble(pt0, pt1); 1320 } 1321 1322 String dash = ""; 1323 if (tg.get_DTG() != null && tg.get_DTG1() != null && !tg.get_DTG().isEmpty() && !tg.get_DTG1().isEmpty()) { 1324 dash = " - "; 1325 } 1326 1327 String combinedDTG = tg.get_DTG() + dash + tg.get_DTG1(); 1328 1329 double stringWidth = metrics.stringWidth(combinedDTG); 1330 1331 if (stringWidth < maxDTGWidth) { 1332 // Add on one line 1333 AddModifier(tg, combinedDTG, type, lineFactor1, pt0, pt1); 1334 } else { 1335 // add on two lines 1336 // Use min and max on lineFactors. Always want W1 on top. This fixes when lineFactor < 0 W1 should use lineFactor1 1337 AddModifier(tg, tg.get_DTG() + dash, type, Math.min(lineFactor1, lineFactor2), pt0, pt1); 1338 AddModifier(tg, tg.get_DTG1(), type, Math.max(lineFactor1, lineFactor2), pt0, pt1); 1339 } 1340 } 1341 1342 private static int getVisibleMiddleSegment(TGLight tg, Object clipBounds) { 1343 int middleSegment = -1; 1344 try { 1345 Polygon clipBoundsPoly = null; 1346 Rectangle2D clipRect = null; 1347 boolean useClipRect; // true if clipBounds is Rectangle2D otherwise use clipBoundsPoly 1348 POINT2 pt0 = null, pt1 = null; 1349 double dist = 0; 1350 POINT2 lastPt = null; 1351 long lineType = tg.get_LineType(); 1352 //we want the middle segment to be visible 1353 middleSegment = (tg.Pixels.size() + 1) / 2 - 1; 1354 1355 boolean foundVisibleSegment = false; 1356 if (clipBounds == null) { 1357 return middleSegment; 1358 } 1359 1360 if (ArrayList.class.isAssignableFrom(clipBounds.getClass())) { 1361 useClipRect = false; 1362 clipBoundsPoly = new Polygon(); 1363 ArrayList<Point2D> clipArray = (ArrayList<Point2D>) clipBounds; 1364 for (int j = 0; j < clipArray.size(); j++) { 1365 int x = (int) (clipArray.get(j)).getX(); 1366 int y = (int) (clipArray.get(j)).getY(); 1367 clipBoundsPoly.addPoint(x, y); 1368 } 1369 } else if (Rectangle2D.class.isAssignableFrom(clipBounds.getClass())) { 1370 useClipRect = true; 1371 clipRect = (Rectangle2D) clipBounds; 1372 } else { 1373 return middleSegment; 1374 } 1375 1376 //walk through the segments to find the first visible segment from the middle 1377 for (int j = middleSegment; j < tg.Pixels.size() - 1; j++) { 1378 pt0 = tg.Pixels.get(j); 1379 pt1 = tg.Pixels.get(j + 1); 1380 dist = lineutility.CalcDistanceDouble(pt0, pt1); 1381 if (dist < 5) { 1382 continue; 1383 } 1384 //diagnostic 1385 if (j > 0 && lineType == TacticalLines.BOUNDARY) { 1386 if (lastPt == null) { 1387 lastPt = tg.Pixels.get(j - 1); 1388 } 1389 if (DoublesBack(lastPt, pt0, pt1)) { 1390 continue; 1391 } 1392 1393 lastPt = null; 1394 } 1395 //if either of the points is within the bound then most of the segment is visible 1396 if (!useClipRect) { 1397 if (clipBoundsPoly.contains(pt0.x, pt0.y) || clipBoundsPoly.contains(pt1.x, pt1.y)) { 1398 middleSegment = j; 1399 foundVisibleSegment = true; 1400 break; 1401 } 1402 } else { 1403 if (clipRect.contains(pt0.x, pt0.y) || clipRect.contains(pt1.x, pt1.y)) { 1404 middleSegment = j; 1405 foundVisibleSegment = true; 1406 break; 1407 } 1408 } 1409 } 1410 1411 if (!foundVisibleSegment) { 1412 for (int j = middleSegment; j > 0; j--) { 1413 pt0 = tg.Pixels.get(j); 1414 pt1 = tg.Pixels.get(j - 1); 1415 dist = lineutility.CalcDistanceDouble(pt0, pt1); 1416 if (dist < 5) { 1417 continue; 1418 } 1419 //diagnostic 1420 if (lineType == TacticalLines.BOUNDARY) { 1421 if (lastPt == null) { 1422 lastPt = tg.Pixels.get(j - 1); 1423 } 1424 1425 if ( DoublesBack(lastPt, pt0, pt1)) { 1426 continue; 1427 } 1428 1429 lastPt = null; 1430 } 1431 //if either of the points is within the bound then most of the segment is visible 1432 if (!useClipRect) { 1433 if (clipBoundsPoly.contains(pt0.x, pt0.y) || clipBoundsPoly.contains(pt1.x, pt1.y)) { 1434 middleSegment = j - 1; 1435 foundVisibleSegment = true; 1436 break; 1437 } 1438 } else { 1439 if (clipRect.contains(pt0.x, pt0.y) || clipRect.contains(pt1.x, pt1.y)) { 1440 middleSegment = j - 1; 1441 foundVisibleSegment = true; 1442 break; 1443 } 1444 } 1445 } 1446 } 1447 1448 if (!foundVisibleSegment) { 1449 middleSegment = tg.Pixels.size() / 2 - 1; 1450 } 1451 } catch (Exception exc) { 1452 ErrorLogger.LogException(_className, "getMiddleSegment", 1453 new RendererException("Failed inside getMiddleSegment", exc)); 1454 } 1455 return middleSegment; 1456 } 1457 1458 /** 1459 * called repeatedly by RemoveModifiers to remove modifiers which fall 1460 * outside the symbol MBR 1461 * 1462 * @param tg 1463 * @param modifierType 1464 */ 1465 private static void removeModifier(TGLight tg, 1466 String modifierType) { 1467 try { 1468 int j = 0; 1469 Modifier2 modifier = null; 1470 int n = tg.Pixels.size(); 1471 //for (j = 0; j < tg.modifiers.size(); j++) 1472 for (j = 0; j < n; j++) { 1473 modifier = tg.modifiers.get(j); 1474 1475 if (modifier.textID == null) { 1476 continue; 1477 } 1478 1479 if (modifier.textID.equalsIgnoreCase(modifierType)) { 1480 tg.modifiers.remove(modifier); 1481 break; 1482 } 1483 } 1484 } catch (Exception exc) { 1485 ErrorLogger.LogException(_className, "removeModifier", 1486 new RendererException("Failed inside removeModifier", exc)); 1487 } 1488 } 1489 1490 /** 1491 * removes text modifiers for CPOF tactical areas which do not fit inside 1492 * the symbol MBR 1493 * 1494 * @param tg 1495 * @param g2d 1496 * @param isTextFlipped true if text is flipped from the last segment 1497 * orientation 1498 * @param iteration the instance count for this modifier 1499 */ 1500 public static void RemoveModifiers(TGLight tg, 1501 Graphics2D g2d, 1502 boolean isTextFlipped, 1503 int iteration) { 1504 try { 1505 //CPOF clients only 1506 if (!tg.get_Client().equalsIgnoreCase("cpof2d") && !tg.get_Client().equalsIgnoreCase("cpof3d")) { 1507 return; 1508 } 1509 1510 int j = 0; 1511 Polygon mbrPoly = null; 1512 //if it's a change 1 rectangular area then use the pixels instead of the mbr 1513 //because those use aboveMiddle to build angular text 1514 switch (tg.get_LineType()) { 1515 case TacticalLines.RECTANGULAR: 1516 case TacticalLines.CUED_ACQUISITION: 1517 case TacticalLines.ACA_RECTANGULAR: //aboveMiddle modifiers: slanted text 1518 case TacticalLines.FFA_RECTANGULAR: 1519 case TacticalLines.NFA_RECTANGULAR: 1520 case TacticalLines.RFA_RECTANGULAR: 1521 case TacticalLines.KILLBOXBLUE_RECTANGULAR: 1522 case TacticalLines.KILLBOXPURPLE_RECTANGULAR: 1523 case TacticalLines.FSA_RECTANGULAR: 1524 case TacticalLines.SHIP_AOI_RECTANGULAR: 1525 case TacticalLines.DEFENDED_AREA_RECTANGULAR: 1526 case TacticalLines.ATI_RECTANGULAR: 1527 case TacticalLines.CFFZ_RECTANGULAR: 1528 case TacticalLines.SENSOR_RECTANGULAR: 1529 case TacticalLines.CENSOR_RECTANGULAR: 1530 case TacticalLines.DA_RECTANGULAR: 1531 case TacticalLines.CFZ_RECTANGULAR: 1532 case TacticalLines.ZOR_RECTANGULAR: 1533 case TacticalLines.TBA_RECTANGULAR: 1534 case TacticalLines.TVAR_RECTANGULAR: 1535 case TacticalLines.ACA_CIRCULAR: 1536 case TacticalLines.CIRCULAR: 1537 case TacticalLines.BDZ: 1538 case TacticalLines.FSA_CIRCULAR: 1539 case TacticalLines.NOTACK: 1540 case TacticalLines.ATI_CIRCULAR: 1541 case TacticalLines.CFFZ_CIRCULAR: 1542 case TacticalLines.SENSOR_CIRCULAR: 1543 case TacticalLines.CENSOR_CIRCULAR: 1544 case TacticalLines.DA_CIRCULAR: 1545 case TacticalLines.CFZ_CIRCULAR: 1546 case TacticalLines.ZOR_CIRCULAR: 1547 case TacticalLines.TBA_CIRCULAR: 1548 case TacticalLines.TVAR_CIRCULAR: 1549 case TacticalLines.FFA_CIRCULAR: 1550 case TacticalLines.NFA_CIRCULAR: 1551 case TacticalLines.RFA_CIRCULAR: 1552 case TacticalLines.KILLBOXBLUE_CIRCULAR: 1553 case TacticalLines.KILLBOXPURPLE_CIRCULAR: 1554 if (tg.modifiers == null || tg.modifiers.isEmpty() || iteration != 1) { 1555 return; 1556 } 1557 1558 mbrPoly = new Polygon(); 1559 int n = tg.Pixels.size(); 1560 //for (j = 0; j < tg.Pixels.size(); j++) 1561 for (j = 0; j < n; j++) { 1562 mbrPoly.addPoint((int) tg.Pixels.get(j).x, (int) tg.Pixels.get(j).y); 1563 } 1564 1565 break; 1566 default: //area modifiers: horizontal text 1567 if (clsUtility.isClosedPolygon(tg.get_LineType()) == false || iteration != 0) { 1568 return; 1569 } 1570 if (tg.modifiers == null || tg.modifiers.isEmpty()) { 1571 return; 1572 } 1573 1574 mbrPoly = new Polygon(); 1575 int t = tg.Pixels.size(); 1576 //for (j = 0; j < tg.Pixels.size(); j++) 1577 for (j = 0; j < t; j++) { 1578 mbrPoly.addPoint((int) tg.Pixels.get(j).x, (int) tg.Pixels.get(j).y); 1579 } 1580 } 1581 1582 Font font = null; 1583 font = tg.get_Font(); //might have to change this 1584 if (font == null) { 1585 font = g2d.getFont(); 1586 } 1587 g2d.setFont(font); 1588 FontMetrics metrics = g2d.getFontMetrics(); 1589 1590 double stringWidth = 0, stringHeight = 0; 1591 boolean wfits = true, w1fits = true, ww1fits = true, hfits = true, h1fits = true, h2fits = true; 1592 Modifier2 modifier = null; 1593 String modifierType = ""; 1594 String s = ""; 1595 POINT2 pt0 = null, pt1 = null, pt2 = null, pt3 = null, pt4 = null; 1596 double lineFactor = 0; 1597 double x = 0, y = 0; 1598 double x1 = 0, y1 = 0, x2 = 0, y2 = 0; //logic as follows: 1599 //we have to loop through to determine if each modifiers fits and set its fitsMBR member 1600 //then run a 2nd loop to remove groups of modifiers based on whether any of the others do not fit 1601 //e.g. if W does not fit then remove W and W1 modifiers 1602 int n = tg.modifiers.size(); 1603 //for (j = 0; j < tg.modifiers.size(); j++) 1604 for (j = 0; j < n; j++) { 1605 modifier = tg.modifiers.get(j); 1606 if (modifier.textID == null || modifier.textID.isEmpty()) { 1607 continue; 1608 } 1609 1610 modifierType = modifier.textID; 1611 lineFactor = modifier.lineFactor; 1612 1613 if (isTextFlipped) { 1614 lineFactor = -lineFactor; 1615 } 1616 1617 s = modifier.text; 1618 if (s == null || s.equals("")) { 1619 continue; 1620 } 1621 stringWidth = (double) metrics.stringWidth(s) + 1; 1622 stringHeight = (double) font.getSize(); 1623 1624 if (modifier.type == area) { 1625 pt0 = modifier.textPath[0]; 1626 x1 = pt0.x; 1627 y1 = pt0.y; 1628 x = (int) x1 - (int) stringWidth / 2; 1629 y = (int) y1 + (int) (stringHeight / 2) + (int) (1.25 * lineFactor * stringHeight); 1630 //pt1 = modifier.textPath[1]; 1631 x2 = (int) x1 + (int) stringWidth / 2; 1632 y2 = (int) y1 + (int) (stringHeight / 2) + (int) (1.25 * lineFactor * stringHeight); 1633 if (mbrPoly.contains(x, y) && mbrPoly.contains(x2, y2)) { 1634 modifier.fitsMBR = true; 1635 } else { 1636 modifier.fitsMBR = false; 1637 } 1638 } else if (modifier.type == aboveMiddle) { 1639 pt0 = modifier.textPath[0]; 1640 pt1 = modifier.textPath[1]; 1641 //double dist=lineutility.CalcDistanceDouble(pt0, pt1); 1642 POINT2 ptCenter = lineutility.MidPointDouble(pt0, pt1, 0); 1643 pt0 = lineutility.ExtendAlongLineDouble(ptCenter, pt0, stringWidth / 2); 1644 pt1 = lineutility.ExtendAlongLineDouble(ptCenter, pt1, stringWidth / 2); 1645 1646 if (lineFactor >= 0) { 1647 pt2 = lineutility.ExtendDirectedLine(ptCenter, pt0, pt0, 3, Math.abs((lineFactor) * stringHeight)); 1648 } else { 1649 pt2 = lineutility.ExtendDirectedLine(ptCenter, pt0, pt0, 2, Math.abs((lineFactor) * stringHeight)); 1650 } 1651 1652 if (lineFactor >= 0) { 1653 pt3 = lineutility.ExtendDirectedLine(ptCenter, pt1, pt1, 3, Math.abs((lineFactor) * stringHeight)); 1654 } else { 1655 pt3 = lineutility.ExtendDirectedLine(ptCenter, pt1, pt1, 2, Math.abs((lineFactor) * stringHeight)); 1656 } 1657 1658 x1 = pt2.x; 1659 y1 = pt2.y; 1660 x2 = pt3.x; 1661 y2 = pt3.y; 1662 if (mbrPoly.contains(x1, y1) && mbrPoly.contains(x2, y2)) { 1663 modifier.fitsMBR = true; 1664 } else { 1665 modifier.fitsMBR = false; 1666 } 1667 } else { 1668 modifier.fitsMBR = true; 1669 } 1670 } 1671 n = tg.modifiers.size(); 1672 //for (j = 0; j < tg.modifiers.size(); j++) 1673 for (j = 0; j < n; j++) { 1674 modifier = tg.modifiers.get(j); 1675 if (modifier.textID == null || modifier.textID.isEmpty()) { 1676 continue; 1677 } 1678 1679 if (modifier.fitsMBR == false) { 1680 if (modifier.textID.equalsIgnoreCase("W")) { 1681 wfits = false; 1682 } else if (modifier.textID.equalsIgnoreCase("W1")) { 1683 w1fits = false; 1684 } else if (modifier.textID.equalsIgnoreCase("W+W1")) { 1685 ww1fits = false; 1686 } else if (modifier.textID.equalsIgnoreCase("H")) { 1687 hfits = false; 1688 } else if (modifier.textID.equalsIgnoreCase("H1")) { 1689 h1fits = false; 1690 } else if (modifier.textID.equalsIgnoreCase("H2")) { 1691 h2fits = false; 1692 } 1693 } 1694 } 1695 if (wfits == false || w1fits == false) { 1696 removeModifier(tg, "W"); 1697 removeModifier(tg, "W1"); 1698 } 1699 if (ww1fits == false) { 1700 removeModifier(tg, "W+W1"); 1701 } 1702 if (hfits == false || h1fits == false || h2fits == false) { 1703 removeModifier(tg, "H"); 1704 removeModifier(tg, "H1"); 1705 removeModifier(tg, "H2"); 1706 } 1707 1708 } catch (Exception exc) { 1709 ErrorLogger.LogException(_className, "RemoveModifeirs", 1710 new RendererException("Failed inside RemoveModifiers", exc)); 1711 } 1712 } 1713 1714 /** 1715 * Calculates a segment in the pixels middle by length to hold a string. 1716 * 1717 * @param tg 1718 * @param stringWidth 1719 * @param segPt0 1720 * @param segPt1 1721 */ 1722 private static void getPixelsMiddleSegment(TGLight tg, 1723 double stringWidth, 1724 POINT2 segPt0, 1725 POINT2 segPt1) { 1726 try { 1727 switch (tg.get_LineType()) { 1728 case TacticalLines.CFL: 1729 break; 1730 default: 1731 return; 1732 } 1733 int totalLength = 0; 1734 int j = 0; 1735 double dist = 0; 1736 double mid = 0; 1737 double remainder = 0; 1738 POINT2 pt0 = null, pt1 = null, pt2 = null, pt3 = null; 1739 POINT2 midPt = null; 1740 //first get the total length of all the segments 1741 int n = tg.Pixels.size(); 1742 //for (j = 0; j < tg.Pixels.size() - 1; j++) 1743 for (j = 0; j < n - 1; j++) { 1744 dist = lineutility.CalcDistanceDouble(tg.Pixels.get(j), tg.Pixels.get(j + 1)); 1745 totalLength += dist; 1746 } 1747 mid = totalLength / 2; 1748 totalLength = 0; 1749 //walk thru the segments to find the middle 1750 //for (j = 0; j < tg.Pixels.size() - 1; j++) 1751 for (j = 0; j < n - 1; j++) { 1752 dist = lineutility.CalcDistanceDouble(tg.Pixels.get(j), tg.Pixels.get(j + 1)); 1753 totalLength += dist; 1754 if (totalLength >= mid)//current segment contains the middle 1755 { 1756 remainder = totalLength - mid; 1757 pt0 = tg.Pixels.get(j); 1758 pt1 = tg.Pixels.get(j + 1); 1759 //calculate the pixels mid point 1760 midPt = lineutility.ExtendAlongLineDouble2(pt1, pt0, remainder); 1761 pt2 = lineutility.ExtendAlongLineDouble2(midPt, pt0, stringWidth / 2); 1762 pt3 = lineutility.ExtendAlongLineDouble2(midPt, pt1, stringWidth / 2); 1763 segPt0.x = pt2.x; 1764 segPt0.y = pt2.y; 1765 segPt1.x = pt3.x; 1766 segPt1.y = pt3.y; 1767 break; 1768 } 1769 } 1770 } catch (Exception exc) { 1771 ErrorLogger.LogException(_className, "getPixelsMidpoint", 1772 new RendererException("Failed inside getPixelsMidpoint", exc)); 1773 } 1774 } 1775 1776 private static double getChange1Height(TGLight tg) { 1777 double height = 0; 1778 try { 1779 switch (tg.get_LineType()) { 1780 //case TacticalLines.PAA_RECTANGULAR: 1781 case TacticalLines.FSA_RECTANGULAR: 1782 case TacticalLines.SHIP_AOI_RECTANGULAR: 1783 case TacticalLines.DEFENDED_AREA_RECTANGULAR: 1784 case TacticalLines.FFA_RECTANGULAR: 1785 case TacticalLines.ACA_RECTANGULAR: 1786 case TacticalLines.NFA_RECTANGULAR: 1787 case TacticalLines.RFA_RECTANGULAR: 1788 case TacticalLines.ATI_RECTANGULAR: 1789 case TacticalLines.CFFZ_RECTANGULAR: 1790 case TacticalLines.SENSOR_RECTANGULAR: 1791 case TacticalLines.CENSOR_RECTANGULAR: 1792 case TacticalLines.DA_RECTANGULAR: 1793 case TacticalLines.CFZ_RECTANGULAR: 1794 case TacticalLines.ZOR_RECTANGULAR: 1795 case TacticalLines.TBA_RECTANGULAR: 1796 case TacticalLines.TVAR_RECTANGULAR: 1797 case TacticalLines.KILLBOXBLUE_RECTANGULAR: 1798 case TacticalLines.KILLBOXPURPLE_RECTANGULAR: 1799 break; 1800 default: 1801 return 0; 1802 } 1803 double x1 = tg.Pixels.get(0).x; 1804 double y1 = tg.Pixels.get(0).y; 1805 double x2 = tg.Pixels.get(1).x; 1806 double y2 = tg.Pixels.get(1).y; 1807 double deltax = x2 - x1; 1808 double deltay = y2 - y1; 1809 height = Math.sqrt(deltax * deltax + deltay * deltay); 1810 } catch (Exception exc) { 1811 ErrorLogger.LogException(_className, "getChange1Height", 1812 new RendererException("Failed inside getChange1Height", exc)); 1813 } 1814 return height; 1815 } 1816 1817 /** 1818 * scale the line factor for closed areas 1819 * 1820 * @param tg 1821 */ 1822 private static void scaleModifiers(TGLight tg) { 1823 try { 1824 if (RendererSettings.getInstance().getAutoCollapseModifiers() == false) { 1825 return; 1826 } 1827 if (!tg.get_Client().equalsIgnoreCase("ge")) { 1828 return; 1829 } 1830 //exit if there are no modifiers or it's not a closed area 1831 if (tg.modifiers == null || tg.modifiers.isEmpty()) { 1832 return; 1833 } 1834 int linetype = tg.get_LineType(); 1835 boolean isClosedPolygon = clsUtility.isClosedPolygon(linetype); 1836 boolean isChange1Area = clsUtility.IsChange1Area(linetype); 1837 if (!isClosedPolygon && !isChange1Area) { 1838 return; 1839 } 1840 switch(linetype) 1841 { 1842 case TacticalLines.PAA_CIRCULAR: 1843 case TacticalLines.PAA_RECTANGULAR: 1844 case TacticalLines.RECTANGULAR_TARGET: 1845 case TacticalLines.RANGE_FAN: 1846 case TacticalLines.RANGE_FAN_SECTOR: 1847 case TacticalLines.RADAR_SEARCH: 1848 return; 1849 default: 1850 break; 1851 } 1852 POINT2 ptUl = new POINT2(), ptUr = new POINT2(), ptLr = new POINT2(), ptLl = new POINT2(); 1853 GetMBR(tg, ptUl, ptUr, ptLr, ptLl); 1854 int sz = tg.get_Font().getSize(); 1855 //heightMBR is half the MBR height 1856 //double heightMBR=Math.abs(ptLr.y-ptUr.y)/2; 1857 double heightMBR = 0; 1858 double change1Height = getChange1Height(tg); 1859 if (change1Height <= 0) { 1860 heightMBR = Math.abs(ptLr.y - ptUr.y) / 2; 1861 } else { 1862 heightMBR = change1Height; 1863 } 1864 1865 double heightModifiers = 0; 1866 ArrayList<Modifier2> modifiers = tg.modifiers; 1867 Modifier2 modifier = null; 1868 double minLF = Integer.MAX_VALUE; 1869 int j = 0; 1870 boolean isValid = false; 1871 for (j = 0; j < modifiers.size(); j++) { 1872 modifier = modifiers.get(j); 1873 //if(modifier.type == area) 1874 //type3Area=true; 1875 if (modifier.type == toEnd) { 1876 continue; 1877 } 1878 if (modifier.type == aboveMiddle && isChange1Area == false) { 1879 continue; 1880 } 1881 if (modifier.lineFactor < minLF) { 1882 minLF = modifier.lineFactor; 1883 } 1884 isValid = true; 1885 } 1886 //if there are no 'area' modifiers then exit early 1887 if (!isValid) { 1888 return; 1889 } 1890 1891 heightModifiers = Math.abs(minLF) * sz; 1892 boolean expandModifiers = false, shrinkModifiers = false; 1893 if (heightModifiers > heightMBR) { 1894 shrinkModifiers = true; 1895 } else if (heightModifiers < 0.5 * heightMBR) { 1896 expandModifiers = true; 1897 } 1898 1899 boolean addEllipsis = false; 1900 //modifierE is ellipses modifier 1901 Modifier2 modifierE = new Modifier2(); 1902 if (expandModifiers) { 1903 double factor = heightMBR / heightModifiers; 1904 factor = 1 + (factor - 1) / 4; 1905 if (factor > 2) { 1906 factor = 2; 1907 } 1908 for (j = 0; j < modifiers.size(); j++) { 1909 modifier = modifiers.get(j); 1910 if(modifier.type==aboveMiddle) 1911 { 1912 if(isChange1Area==false) 1913 continue; 1914 } 1915 else if(modifier.type!=area) 1916 continue; 1917 1918 modifier.lineFactor *= factor; 1919 } 1920 } else if (shrinkModifiers) { 1921 double deltaLF = (heightModifiers - heightMBR) / sz; 1922 double newLF = 0; 1923 //use maxLF for the ellipsis modifier 1924 double maxLF = 0; 1925 for (j = 0; j < modifiers.size(); j++) { 1926 modifier = modifiers.get(j); 1927 if(modifier.type==aboveMiddle) 1928 { 1929 if(isChange1Area==false) 1930 continue; 1931 } 1932 else if(modifier.type!=area) 1933 continue; 1934 newLF = modifier.lineFactor + deltaLF; 1935 if (Math.abs(newLF * sz) >= heightMBR) { 1936 //flag the modifier to remove 1937 if (modifier.lineFactor > minLF) { 1938 modifierE.type = modifier.type; 1939 modifier.type = 7; 1940 if (!modifier.text.isEmpty()) { 1941 addEllipsis = true; 1942 } 1943 } 1944 modifier.lineFactor = newLF; 1945 //modifierE.type=area; 1946 //modifierE.type=modifier.type; 1947 modifierE.textPath = modifier.textPath; 1948 continue; 1949 } 1950 modifier.lineFactor = newLF; 1951 } 1952 ArrayList<Modifier2> modifiers2 = new ArrayList(); 1953 for (j = 0; j < modifiers.size(); j++) { 1954 modifier = modifiers.get(j); 1955 if (modifier.type != 7) { 1956 if (modifier.lineFactor > maxLF) { 1957 maxLF = modifier.lineFactor; 1958 } 1959 modifiers2.add(modifier); 1960 } 1961 } 1962 if (addEllipsis) { 1963 Character letter = (char) 9679; 1964 String s = Character.toString(letter); 1965 String echelonSymbol = s + s + s; 1966 modifierE.text = echelonSymbol; 1967 modifierE.lineFactor = maxLF + 1; 1968 modifiers2.add(modifierE); 1969 } 1970 tg.modifiers = modifiers2; 1971 } //end shrink modifiers 1972 } catch (Exception exc) { 1973 ErrorLogger.LogException(_className, "scaleModifiers", 1974 new RendererException("Failed inside scaleModifiers", exc)); 1975 } 1976 } 1977 1978 /** 1979 * Calculate modifiers identical to addModifiers except use geodesic 1980 * calculations for the center point. 1981 * 1982 * @param tg 1983 * @param g2d 1984 * @param clipBounds 1985 * @param converter 1986 */ 1987 public static void AddModifiersGeo(TGLight tg, 1988 Graphics2D g2d, 1989 Object clipBounds, 1990 IPointConversion converter) { 1991 try { 1992 //exit early for those not affected 1993 if (tg.Pixels == null || tg.Pixels.isEmpty()) { 1994 return; 1995 } 1996 ArrayList<POINT2> origPoints = null; 1997 Font font = tg.get_Font(); 1998 if (font == null) { 1999 font = g2d.getFont(); 2000 } 2001 g2d.setFont(font); 2002 2003 boolean shiftLines = Channels.getShiftLines(); 2004 boolean usas = false, foundSegment = false; 2005 double csFactor = 1d, dist = 0, dist2 = 0;//this will be used for text spacing the 3d map (CommandCight) 2006 POINT2 midPt = null; 2007 int northestPtIndex = 0; 2008 int southestPtIndex = 0; 2009 POINT2 northestPt = null; 2010 POINT2 southestPt = null; 2011 2012 Rectangle2D clipRect = null; 2013 ArrayList<Point2D> clipArray = null; 2014 if (clipBounds != null && ArrayList.class.isAssignableFrom(clipBounds.getClass())) { 2015 clipArray = (ArrayList<Point2D>) clipBounds; 2016 } 2017 if (clipBounds != null && Rectangle2D.Double.class.isAssignableFrom(clipBounds.getClass())) { 2018 clipRect = (Rectangle2D.Double) clipBounds; 2019 } 2020 2021 FontMetrics metrics = g2d.getFontMetrics(); 2022 int stringWidth = 0, stringWidth2 = 0; 2023 String WDash = ""; // Dash between W and W1 if they're not empty 2024 String TSpace = "", TDash = ""; // Space or dash between label and T modifier if T isn't empty 2025 if (tg.get_DTG() != null && tg.get_DTG1() != null && !tg.get_DTG().isEmpty() && !tg.get_DTG1().isEmpty()) { 2026 WDash = " - "; 2027 } 2028 if (tg.get_Name() != null && !tg.get_Name().isEmpty()) { 2029 TSpace = " "; 2030 TDash = " - "; 2031 } 2032 2033 if (tg.get_Client().equals("cpof3d")) { 2034 csFactor = 0.9d; 2035 } 2036 2037 switch (tg.get_LineType()) { 2038 case TacticalLines.SERIES: 2039 case TacticalLines.STRIKWARN: 2040 case TacticalLines.MSR: 2041 case TacticalLines.MSR_ONEWAY: 2042 case TacticalLines.MSR_TWOWAY: 2043 case TacticalLines.MSR_ALT: 2044 case TacticalLines.ASR: 2045 case TacticalLines.ASR_ONEWAY: 2046 case TacticalLines.ASR_TWOWAY: 2047 case TacticalLines.ASR_ALT: 2048 case TacticalLines.TRAFFIC_ROUTE: 2049 case TacticalLines.TRAFFIC_ROUTE_ONEWAY: 2050 case TacticalLines.TRAFFIC_ROUTE_ALT: 2051 case TacticalLines.DHA_REVD: 2052 case TacticalLines.DHA: 2053 case TacticalLines.KILL_ZONE: 2054 case TacticalLines.EPW: 2055 case TacticalLines.UXO: 2056 case TacticalLines.FARP: 2057 case TacticalLines.BSA: 2058 case TacticalLines.DSA: 2059 case TacticalLines.CSA: 2060 case TacticalLines.RSA: 2061 case TacticalLines.THUNDERSTORMS: 2062 case TacticalLines.ICING: 2063 case TacticalLines.FREEFORM: 2064 case TacticalLines.RHA: 2065 case TacticalLines.LINTGT: 2066 case TacticalLines.LINTGTS: 2067 case TacticalLines.FPF: 2068 case TacticalLines.GAP: 2069 case TacticalLines.DEPICT: 2070 case TacticalLines.AIRHEAD: 2071 case TacticalLines.FSA: 2072 case TacticalLines.DIRATKAIR: 2073 case TacticalLines.OBJ: 2074 case TacticalLines.AO: 2075 case TacticalLines.ACA: 2076 case TacticalLines.FFA: 2077 case TacticalLines.PAA: 2078 case TacticalLines.NFA: 2079 case TacticalLines.RFA: 2080 case TacticalLines.ATI: 2081 case TacticalLines.CFFZ: 2082 case TacticalLines.CFZ: 2083 case TacticalLines.TBA: 2084 case TacticalLines.TVAR: 2085 case TacticalLines.KILLBOXBLUE: 2086 case TacticalLines.KILLBOXPURPLE: 2087 case TacticalLines.ZOR: 2088 case TacticalLines.DA: 2089 case TacticalLines.SENSOR: 2090 case TacticalLines.CENSOR: 2091 case TacticalLines.SMOKE: 2092 case TacticalLines.BATTLE: 2093 case TacticalLines.PNO: 2094 case TacticalLines.PDF: 2095 case TacticalLines.NAI: 2096 case TacticalLines.TAI: 2097 case TacticalLines.BASE_CAMP_REVD: 2098 case TacticalLines.BASE_CAMP: 2099 case TacticalLines.GUERILLA_BASE_REVD: 2100 case TacticalLines.GUERILLA_BASE: 2101 case TacticalLines.GENERIC_AREA: 2102 case TacticalLines.ATKPOS: 2103 case TacticalLines.ASSAULT: 2104 case TacticalLines.WFZ_REVD: 2105 case TacticalLines.WFZ: 2106 case TacticalLines.OBSFAREA: 2107 case TacticalLines.OBSAREA: 2108 case TacticalLines.ROZ: 2109 case TacticalLines.AARROZ: 2110 case TacticalLines.UAROZ: 2111 case TacticalLines.WEZ: 2112 case TacticalLines.FEZ: 2113 case TacticalLines.JEZ: 2114 case TacticalLines.FAADZ: 2115 case TacticalLines.HIDACZ: 2116 case TacticalLines.MEZ: 2117 case TacticalLines.LOMEZ: 2118 case TacticalLines.HIMEZ: 2119 case TacticalLines.SAAFR: 2120 case TacticalLines.AC: 2121 case TacticalLines.MRR: 2122 case TacticalLines.SL: 2123 case TacticalLines.TC: 2124 case TacticalLines.SC: 2125 case TacticalLines.LLTR: 2126 case TacticalLines.AIRFIELD: 2127 case TacticalLines.GENERAL: 2128 case TacticalLines.JTAA: 2129 case TacticalLines.SAA: 2130 case TacticalLines.SGAA: 2131 case TacticalLines.FORT_REVD: 2132 case TacticalLines.FORT: 2133 case TacticalLines.ENCIRCLE: 2134 case TacticalLines.ASSY: 2135 case TacticalLines.EA: 2136 case TacticalLines.DZ: 2137 case TacticalLines.EZ: 2138 case TacticalLines.LZ: 2139 case TacticalLines.PZ: 2140 case TacticalLines.LAA: 2141 case TacticalLines.BOUNDARY: 2142 case TacticalLines.MINED: 2143 case TacticalLines.FENCED: 2144 case TacticalLines.PL: 2145 case TacticalLines.DECISION_LINE: 2146 case TacticalLines.FEBA: 2147 case TacticalLines.FCL: 2148 case TacticalLines.HOLD: 2149 case TacticalLines.BRDGHD: 2150 case TacticalLines.HOLD_GE: 2151 case TacticalLines.BRDGHD_GE: 2152 case TacticalLines.LOA: 2153 case TacticalLines.LOD: 2154 case TacticalLines.LL: 2155 case TacticalLines.EWL: 2156 case TacticalLines.RELEASE: 2157 case TacticalLines.HOL: 2158 case TacticalLines.BHL: 2159 case TacticalLines.LDLC: 2160 case TacticalLines.PLD: 2161 case TacticalLines.NFL: 2162 case TacticalLines.MFP: 2163 case TacticalLines.FSCL: 2164 case TacticalLines.BCL_REVD: 2165 case TacticalLines.BCL: 2166 case TacticalLines.ICL: 2167 case TacticalLines.IFF_OFF: 2168 case TacticalLines.IFF_ON: 2169 case TacticalLines.GENERIC_LINE: 2170 case TacticalLines.CFL: 2171 case TacticalLines.TRIP: 2172 case TacticalLines.RFL: 2173 case TacticalLines.FLOT: 2174 case TacticalLines.LC: 2175 case TacticalLines.CATK: 2176 case TacticalLines.CATKBYFIRE: 2177 case TacticalLines.IL: 2178 case TacticalLines.DRCL: 2179 case TacticalLines.RETIRE: 2180 case TacticalLines.PURSUIT: 2181 case TacticalLines.FPOL: 2182 case TacticalLines.RPOL: 2183 case TacticalLines.WITHDRAW: 2184 case TacticalLines.DISENGAGE: 2185 case TacticalLines.WDRAWUP: 2186 case TacticalLines.BEARING: 2187 case TacticalLines.BEARING_J: 2188 case TacticalLines.BEARING_RDF: 2189 case TacticalLines.ELECTRO: 2190 case TacticalLines.BEARING_EW: 2191 case TacticalLines.ACOUSTIC: 2192 case TacticalLines.ACOUSTIC_AMB: 2193 case TacticalLines.TORPEDO: 2194 case TacticalLines.OPTICAL: 2195 case TacticalLines.RIP: 2196 case TacticalLines.DEMONSTRATE: 2197 case TacticalLines.BOMB: 2198 case TacticalLines.ZONE: 2199 case TacticalLines.AT: 2200 case TacticalLines.STRONG: 2201 case TacticalLines.MSDZ: 2202 case TacticalLines.SCREEN: 2203 case TacticalLines.COVER: 2204 case TacticalLines.GUARD: 2205 case TacticalLines.DELAY: 2206 case TacticalLines.TGMF: 2207 case TacticalLines.BIO: 2208 case TacticalLines.BIOT://APP6/E 2209 case TacticalLines.CHEM: 2210 case TacticalLines.CHEMT://APP6/E 2211 case TacticalLines.NUC: 2212 case TacticalLines.RAD: 2213 case TacticalLines.RADT://APP6/E 2214 case TacticalLines.MINE_LINE: 2215 case TacticalLines.ANCHORAGE_LINE: 2216 case TacticalLines.ANCHORAGE_AREA: 2217 case TacticalLines.SPT: 2218 case TacticalLines.FRONTAL_ATTACK: 2219 case TacticalLines.TURNING_MOVEMENT: 2220 case TacticalLines.MOVEMENT_TO_CONTACT: 2221 case TacticalLines.AIRAOA: 2222 case TacticalLines.AAAAA: 2223 case TacticalLines.MAIN: 2224 case TacticalLines.DIRATKSPT: 2225 case TacticalLines.DIRATKGND: 2226 case TacticalLines.LAUNCH_AREA: 2227 case TacticalLines.DEFENDED_AREA_CIRCULAR: 2228 case TacticalLines.RECTANGULAR: 2229 case TacticalLines.CIRCULAR: 2230 case TacticalLines.RECTANGULAR_TARGET: 2231 case TacticalLines.LINE: 2232 case TacticalLines.ASLTXING: 2233 case TacticalLines.BS_LINE: 2234 case TacticalLines.BS_AREA: 2235 case TacticalLines.BBS_LINE: 2236 case TacticalLines.BBS_AREA: 2237 case TacticalLines.PBS_CIRCLE: 2238 case TacticalLines.PBS_ELLIPSE: 2239 case TacticalLines.PBS_RECTANGLE: 2240 case TacticalLines.BBS_POINT: 2241 origPoints = lineutility.getDeepCopy(tg.Pixels); 2242 break; 2243 default: //exit early for those not applicable 2244 return; 2245 } 2246 2247 int linetype = tg.get_LineType(); 2248 int j = 0, k = 0; 2249 double x = 0, y = 0; 2250 2251 int lastIndex = tg.Pixels.size() - 1; 2252 int nextToLastIndex = tg.Pixels.size() - 2; 2253 POINT2 pt0 = new POINT2(tg.Pixels.get(0)); 2254 POINT2 pt1 = null; 2255 POINT2 pt2 = null, pt3 = null; 2256 POINT2 ptLast = new POINT2(tg.Pixels.get(lastIndex)); 2257 POINT2 ptNextToLast = null; 2258 double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0; 2259 2260 if (lastIndex > 0) { 2261 ptNextToLast = new POINT2(tg.Pixels.get(nextToLastIndex)); 2262 } 2263 2264 if (tg.Pixels.size() > 1) { 2265 pt1 = new POINT2(tg.Pixels.get(1)); 2266 } 2267 2268 //prevent vertical paths for modifiers that use toEnd 2269 shiftModifierPath(tg, pt0, pt1, ptLast, ptNextToLast); 2270 2271 String label = GetCenterLabel(tg); 2272 String v=tg.get_V(); 2273 String ap=tg.get_AP(); 2274 Object[] pts = tg.Pixels.toArray(); 2275 //need this for areas and some lines 2276 POINT2 ptCenter = null; 2277 if (converter != null) //cpof uses latlonconverter so cpof passes null for this 2278 { 2279 ptCenter = mdlGeodesic.geodesic_center(tg.LatLongs); 2280 if (ptCenter != null) { 2281 Point2D pt22 = converter.GeoToPixels(new Point2D.Double(ptCenter.x, ptCenter.y)); 2282 ptCenter.x = pt22.getX(); 2283 ptCenter.y = pt22.getY(); 2284 } else { 2285 ptCenter = lineutility.CalcCenterPointDouble2(pts, pts.length); 2286 } 2287 } else { 2288 ptCenter = lineutility.CalcCenterPointDouble2(pts, pts.length); 2289 } 2290 2291 int middleSegment = (tg.Pixels.size() + 1) / 2 - 1; 2292 int middleSegment2 = 0; 2293 2294 if (clipRect != null) { 2295 middleSegment = getVisibleMiddleSegment(tg, clipRect); 2296 } else if (clipArray != null) { 2297 middleSegment = getVisibleMiddleSegment(tg, clipArray); 2298 } 2299 if (tg.Pixels.size() > 2) { 2300 pt2 = tg.Pixels.get(2); 2301 } 2302 if (tg.Pixels.size() > 3) { 2303 pt3 = tg.Pixels.get(3); 2304 } 2305 double TLineFactor = 0, T1LineFactor = 0; 2306 POINT2 lr = new POINT2(tg.Pixels.get(0)); 2307 POINT2 ll = new POINT2(tg.Pixels.get(0)); 2308 POINT2 ul = new POINT2(tg.Pixels.get(0)); 2309 POINT2 ur = new POINT2(tg.Pixels.get(0)); 2310 int index = 0; 2311 int nextIndex = 0; 2312 int size = tg.Pixels.size(); 2313 Line2D line = null; 2314 2315 double dAngle0, dAngle1; 2316 int stringHeight; 2317 2318 switch (linetype) { 2319 case TacticalLines.PL: 2320 AddIntegralAreaModifier(tg, label + TSpace + tg.get_Name(), toEnd, T1LineFactor, pt0, pt1, false); 2321 AddIntegralAreaModifier(tg, label + TSpace + tg.get_Name(), toEnd, T1LineFactor, ptLast, ptNextToLast, false); 2322 break; 2323 case TacticalLines.DECISION_LINE: 2324 if(tg.get_AS() == null || !tg.get_AS().isEmpty()) 2325 tg.set_AS(GENCLookup.getInstance().get3CharCode(SymbolID.getCountryCode(tg.get_SymbolId()))); 2326 Bitmap bi = getImageModifier(tg); 2327 2328 POINT2 ptDP1 = lineutility.ExtendLine2Double(pt1,pt0,bi.getWidth()/2,0); 2329 POINT2 ptDP2 = lineutility.ExtendLine2Double(ptNextToLast, ptLast,bi.getWidth()/2,0); 2330 2331 AddIntegralAreaModifier(tg,bi,toEnd,0,ptDP1,ptDP1,false); 2332 AddIntegralAreaModifier(tg,bi,toEnd,0,ptDP2,ptDP2,false); 2333 break; 2334 case TacticalLines.BS_LINE: 2335 case TacticalLines.BBS_LINE: 2336 if (tg.get_T1() == null || tg.get_T1().isEmpty()) { 2337 AddIntegralAreaModifier(tg, tg.get_Name(), toEnd, T1LineFactor, pt0, pt1, false); 2338 AddIntegralAreaModifier(tg, tg.get_Name(), toEnd, T1LineFactor, ptLast, ptNextToLast, false); 2339 } else { 2340 if (tg.get_T1().equalsIgnoreCase("1")) { 2341 for (j = 0; j < tg.Pixels.size() - 1; j++) { 2342 AddIntegralAreaModifier(tg, tg.get_Name(), aboveMiddle, 0, tg.Pixels.get(j), tg.Pixels.get(j + 1), false); 2343 } 2344 } else if (tg.get_T1().equalsIgnoreCase("2")) { 2345 AddIntegralAreaModifier(tg, tg.get_Name(), toEnd, T1LineFactor, pt0, pt1, false); 2346 AddIntegralAreaModifier(tg, tg.get_Name(), toEnd, T1LineFactor, ptLast, ptNextToLast, false); 2347 } else if (tg.get_T1().equalsIgnoreCase("3")) { 2348 //either end of the polyline 2349 dist = lineutility.CalcDistanceDouble(pt0, pt1); 2350 stringWidth = metrics.stringWidth(tg.get_Name()); 2351 stringWidth /= 2; 2352 pt2 = lineutility.ExtendAlongLineDouble2(pt1, pt0, dist + stringWidth); 2353 AddIntegralAreaModifier(tg, tg.get_Name(), area, 0, pt2, pt2, false); 2354 dist = lineutility.CalcDistanceDouble(ptNextToLast, ptLast); 2355 pt2 = lineutility.ExtendAlongLineDouble2(ptNextToLast, ptLast, dist + stringWidth); 2356 AddIntegralAreaModifier(tg, tg.get_Name(), area, 0, pt2, pt2, false); 2357 //the intermediate points 2358 for (j = 1; j < tg.Pixels.size() - 1; j++) { 2359 AddIntegralAreaModifier(tg, tg.get_Name(), area, 0, tg.Pixels.get(j), tg.Pixels.get(j), false); 2360 } 2361 } else //t1 is set inadvertantly or for other graphics 2362 { 2363 AddIntegralAreaModifier(tg, tg.get_Name(), toEnd, T1LineFactor, pt0, pt1, false); 2364 AddIntegralAreaModifier(tg, tg.get_Name(), toEnd, T1LineFactor, ptLast, ptNextToLast, false); 2365 } 2366 } 2367 break; 2368 case TacticalLines.BS_AREA: 2369 case TacticalLines.BBS_AREA: 2370 AddIntegralAreaModifier(tg, tg.get_Name(), area, 0, ptCenter, ptCenter, false); 2371 break; 2372 case TacticalLines.FEBA: 2373 AddIntegralAreaModifier(tg, label, toEnd, 0, pt0, pt1, false); 2374 AddIntegralAreaModifier(tg, label, toEnd, 0, ptLast, ptNextToLast, false); 2375 break; 2376 // T before label 2377 case TacticalLines.FSCL: 2378 pt0 = tg.Pixels.get(0); 2379 pt1 = tg.Pixels.get(1); 2380 pt2 = tg.Pixels.get(tg.Pixels.size() - 1); 2381 pt3 = tg.Pixels.get(tg.Pixels.size() - 2); 2382 dist = lineutility.CalcDistanceDouble(pt0, pt1); 2383 dist2 = lineutility.CalcDistanceDouble(pt2, pt3); 2384 stringWidth = (int) ((double) metrics.stringWidth(tg.get_Name() + " " + label)); 2385 stringWidth2 = (int) ((double) metrics.stringWidth(tg.get_DTG())); 2386 if (stringWidth2 > stringWidth) { 2387 stringWidth = stringWidth2; 2388 } 2389 2390 if (tg.Pixels.size() == 2) //one segment 2391 { 2392 pt1 = lineutility.ExtendAlongLineDouble(pt0, pt1, stringWidth); 2393 AddModifier2(tg, tg.get_Name() + " " + label , aboveMiddle, -0.7 * csFactor, pt0, pt1, false); 2394 AddModifier2(tg, tg.get_DTG() + WDash, aboveMiddle, 0.7 * csFactor, pt0, pt1, false); 2395 AddModifier2(tg, tg.get_DTG1(), aboveMiddle, 1.7 * csFactor, pt0, pt1, false); 2396 if (dist > 3.5 * stringWidth)//was 28stringwidth+5 2397 { 2398 pt0 = tg.Pixels.get(tg.Pixels.size() - 1); 2399 pt1 = tg.Pixels.get(tg.Pixels.size() - 2); 2400 pt1 = lineutility.ExtendAlongLineDouble(pt0, pt1, stringWidth); 2401 AddModifier2(tg, tg.get_Name() + " " + label, aboveMiddle, -0.7 * csFactor, pt0, pt1, false); 2402 AddModifier2(tg, tg.get_DTG() + WDash, aboveMiddle, 0.7 * csFactor, pt0, pt1, false); 2403 AddModifier2(tg, tg.get_DTG1(), aboveMiddle, 1.7 * csFactor, pt0, pt1, false); 2404 } 2405 } else //more than one semgent 2406 { 2407 double dist3 = lineutility.CalcDistanceDouble(pt0, pt2); 2408 if (dist > stringWidth + 5 || dist >= dist2 || dist3 > stringWidth + 5) { 2409 pt1 = lineutility.ExtendAlongLineDouble(pt0, pt1, stringWidth); 2410 AddModifier2(tg, tg.get_Name() + " " + label, aboveMiddle, -0.7 * csFactor, pt0, pt1, false); 2411 AddModifier2(tg, tg.get_DTG() + WDash, aboveMiddle, 0.7 * csFactor, pt0, pt1, false); 2412 AddModifier2(tg, tg.get_DTG1(), aboveMiddle, 1.7 * csFactor, pt0, pt1, false); 2413 } 2414 if (dist2 > stringWidth + 5 || dist2 > dist || dist3 > stringWidth + 5) { 2415 pt0 = tg.Pixels.get(tg.Pixels.size() - 1); 2416 pt1 = tg.Pixels.get(tg.Pixels.size() - 2); 2417 pt1 = lineutility.ExtendAlongLineDouble(pt0, pt1, stringWidth); 2418 AddModifier2(tg, tg.get_Name() + " " + label, aboveMiddle, -0.7 * csFactor, pt0, pt1, false); 2419 AddModifier2(tg, tg.get_DTG() + WDash, aboveMiddle, 0.7 * csFactor, pt0, pt1, false); 2420 AddModifier2(tg, tg.get_DTG1(), aboveMiddle, 1.7 * csFactor, pt0, pt1, false); 2421 } 2422 } 2423 break; 2424 // T after label 2425 case TacticalLines.ICL: 2426 case TacticalLines.NFL: 2427 case TacticalLines.BCL_REVD: 2428 case TacticalLines.RFL: 2429 case TacticalLines.BCL: 2430 pt0 = tg.Pixels.get(0); 2431 pt1 = tg.Pixels.get(1); 2432 pt2 = tg.Pixels.get(tg.Pixels.size() - 1); 2433 pt3 = tg.Pixels.get(tg.Pixels.size() - 2); 2434 dist = lineutility.CalcDistanceDouble(pt0, pt1); 2435 dist2 = lineutility.CalcDistanceDouble(pt2, pt3); 2436 String TMod = ""; // Don't add parenthesis if T modifier is empty 2437 2438 2439 int version = SymbolID.getVersion(tg.get_SymbolId()); 2440 if(version < SymbolID.Version_2525E) { 2441 TMod = tg.get_Name(); 2442 stringWidth = (int) ((double) metrics.stringWidth(TMod + " " + label)); 2443 } 2444 else if(version == SymbolID.Version_2525E || version == SymbolID.Version_2525Ech1) { 2445 if(linetype == TacticalLines.BCL) { 2446 if (tg.get_Name() != null && !tg.get_Name().isEmpty()) 2447 TMod = " (" + tg.get_Name() + ")"; 2448 stringWidth = (int) ((double) metrics.stringWidth(label + TMod)); 2449 } 2450 else 2451 { 2452 TMod = tg.get_Name(); 2453 stringWidth = (int) ((double) metrics.stringWidth(tg.get_Name() + " " + label)); 2454 } 2455 } 2456 else if((version == SymbolID.Version_APP6Ech2)) { 2457 if (tg.get_Name() != null && !tg.get_Name().isEmpty()) 2458 TMod += " " + tg.get_Name(); 2459 if(tg.get_AS() != null && !tg.get_AS().isEmpty()) 2460 TMod += " (" + tg.get_AS() + ")"; 2461 stringWidth = (int) ((double) metrics.stringWidth(label + TMod)); 2462 2463 } 2464 2465 stringWidth2 = (int) ((double) metrics.stringWidth(tg.get_DTG())); 2466 if (stringWidth2 > stringWidth) { 2467 stringWidth = stringWidth2; 2468 } 2469 2470 if (tg.Pixels.size() == 2) //one segment 2471 { 2472 pt1 = lineutility.ExtendAlongLineDouble(pt0, pt1, stringWidth); 2473 AddModifier2(tg, label + TSpace + TMod, aboveMiddle, -0.7 * csFactor, pt0, pt1, false); 2474 AddModifier2(tg, tg.get_DTG() + WDash, aboveMiddle, 0.7 * csFactor, pt0, pt1, false); 2475 AddModifier2(tg, tg.get_DTG1(), aboveMiddle, 1.7 * csFactor, pt0, pt1, false); 2476 if (dist > 3.5 * stringWidth)//was 28stringwidth+5 2477 { 2478 pt0 = tg.Pixels.get(tg.Pixels.size() - 1); 2479 pt1 = tg.Pixels.get(tg.Pixels.size() - 2); 2480 pt1 = lineutility.ExtendAlongLineDouble(pt0, pt1, stringWidth); 2481 AddModifier2(tg, label + TSpace + TMod, aboveMiddle, -0.7 * csFactor, pt0, pt1, false); 2482 AddModifier2(tg, tg.get_DTG() + WDash, aboveMiddle, 0.7 * csFactor, pt0, pt1, false); 2483 AddModifier2(tg, tg.get_DTG1(), aboveMiddle, 1.7 * csFactor, pt0, pt1, false); 2484 } 2485 } else //more than one semgent 2486 { 2487 double dist3 = lineutility.CalcDistanceDouble(pt0, pt2); 2488 if (dist > stringWidth + 5 || dist >= dist2 || dist3 > stringWidth + 5) { 2489 pt1 = lineutility.ExtendAlongLineDouble(pt0, pt1, stringWidth); 2490 AddModifier2(tg, label + TSpace + TMod, aboveMiddle, -0.7 * csFactor, pt0, pt1, false); 2491 AddModifier2(tg, tg.get_DTG() + WDash, aboveMiddle, 0.7 * csFactor, pt0, pt1, false); 2492 AddModifier2(tg, tg.get_DTG1(), aboveMiddle, 1.7 * csFactor, pt0, pt1, false); 2493 } 2494 if (dist2 > stringWidth + 5 || dist2 > dist || dist3 > stringWidth + 5) { 2495 pt0 = tg.Pixels.get(tg.Pixels.size() - 1); 2496 pt1 = tg.Pixels.get(tg.Pixels.size() - 2); 2497 pt1 = lineutility.ExtendAlongLineDouble(pt0, pt1, stringWidth); 2498 AddModifier2(tg, label + TSpace + TMod, aboveMiddle, -0.7 * csFactor, pt0, pt1, false); 2499 AddModifier2(tg, tg.get_DTG() + WDash, aboveMiddle, 0.7 * csFactor, pt0, pt1, false); 2500 AddModifier2(tg, tg.get_DTG1(), aboveMiddle, 1.7 * csFactor, pt0, pt1, false); 2501 } 2502 } 2503 break; 2504 case TacticalLines.DIRATKSPT: 2505 case TacticalLines.DIRATKAIR: 2506 case TacticalLines.DIRATKGND: 2507 midPt = lineutility.MidPointDouble(pt0, pt1, 0); 2508 //midPt=lineutility.MidPointDouble(pt0, midPt, 0); 2509 AddIntegralAreaModifier(tg, tg.get_Name(), aboveMiddle, 0, pt0, midPt, false); 2510 addDTG(tg, aboveMiddle, csFactor, 2 * csFactor, pt0, pt1, metrics); 2511 break; 2512 case TacticalLines.SPT: 2513 case TacticalLines.FRONTAL_ATTACK: 2514 case TacticalLines.TURNING_MOVEMENT: 2515 case TacticalLines.MOVEMENT_TO_CONTACT: 2516 case TacticalLines.AIRAOA: 2517 case TacticalLines.AAAAA: 2518 case TacticalLines.MAIN: 2519 if (tg.Pixels.size() == 3) //one segment 2520 { 2521 midPt = lineutility.MidPointDouble(pt0, pt1, 0); 2522 AddIntegralAreaModifier(tg, tg.get_DTG() + WDash, aboveMiddle, 0, midPt, midPt, false); 2523 AddIntegralAreaModifier(tg, tg.get_DTG1(), aboveMiddle, csFactor, midPt, midPt, false); 2524 AddIntegralAreaModifier(tg, tg.get_Name(), aboveMiddle, 2 * csFactor, midPt, midPt, false); 2525 2526 } else if (tg.Pixels.size() == 4) //2 segments 2527 { 2528 midPt = lineutility.MidPointDouble(pt1, pt2, 0); 2529 AddIntegralAreaModifier(tg,tg.get_DTG() + WDash, aboveMiddle, 0, midPt, midPt, false); 2530 AddIntegralAreaModifier(tg, tg.get_DTG1(), aboveMiddle, csFactor, midPt, midPt, false); 2531 AddIntegralAreaModifier(tg, tg.get_Name(), aboveMiddle, 2 * csFactor, midPt, midPt, false); 2532 } else // 3 or more segments 2533 { 2534 midPt = lineutility.MidPointDouble(pt1, pt2, 0); 2535 AddIntegralAreaModifier(tg, tg.get_DTG() + WDash, aboveMiddle, -csFactor / 2, midPt, midPt, false); 2536 AddIntegralAreaModifier(tg, tg.get_DTG1(), aboveMiddle, csFactor / 2, midPt, midPt, false); 2537 midPt = lineutility.MidPointDouble(pt2, pt3, 0); 2538 AddIntegralAreaModifier(tg, tg.get_Name(), aboveMiddle, -csFactor / 2, midPt, midPt, false); 2539 } 2540 case TacticalLines.LL: 2541 case TacticalLines.LOD: 2542 case TacticalLines.LDLC: 2543 case TacticalLines.PLD: 2544 case TacticalLines.RELEASE: 2545 case TacticalLines.HOL: 2546 case TacticalLines.BHL: 2547 case TacticalLines.FCL: 2548 case TacticalLines.HOLD: 2549 case TacticalLines.BRDGHD: 2550 case TacticalLines.HOLD_GE: 2551 case TacticalLines.BRDGHD_GE: 2552 case TacticalLines.LOA: 2553 case TacticalLines.IFF_OFF: 2554 case TacticalLines.IFF_ON: 2555 AddIntegralAreaModifier(tg, label, aboveEnd, -csFactor, pt0, pt1, false); 2556 AddIntegralAreaModifier(tg, label, aboveEnd, -csFactor, ptLast, ptNextToLast, false); 2557 break; 2558 case TacticalLines.EWL: 2559 AddIntegralAreaModifier(tg, label, aboveEnd, -csFactor, pt0, pt1, false); 2560 AddIntegralAreaModifier(tg, label, aboveEnd, -csFactor, ptLast, ptNextToLast, false); 2561 tg.set_EchelonSymbol(""); 2562 if (clipRect != null) { 2563 AddBoundaryModifiers(tg, g2d, clipRect); 2564 } else { 2565 AddBoundaryModifiers(tg, g2d, clipArray); 2566 } 2567 break; 2568 case TacticalLines.AIRFIELD: 2569 ur = new POINT2(); 2570 ul = new POINT2(); 2571 ll = new POINT2(); 2572 lr = new POINT2(); 2573 Modifier2.GetMBR(tg, ul, ur, lr, ll); 2574 stringWidth = metrics.stringWidth(tg.get_H()); 2575 pt0.x = ur.x + stringWidth / 2 + 1; 2576 //pt0.x=ptUr.x+1; 2577 //pt0.y=(ptUr.y+ptLr.y)/2-metrics.getFont().getSize() 2578 pt0.y = (ur.y + lr.y) / 2 - font.getSize(); 2579 AddIntegralAreaModifier(tg, tg.get_H(), area, csFactor, pt0, pt0, false); 2580 break; 2581 case TacticalLines.LAUNCH_AREA: 2582 case TacticalLines.DEFENDED_AREA_CIRCULAR: 2583 AddIntegralAreaModifier(tg, label + TDash + tg.get_Name(), area, 0, ptCenter, ptCenter, false); 2584 break; 2585 case TacticalLines.JTAA: 2586 case TacticalLines.SAA: 2587 case TacticalLines.SGAA: 2588 addNModifier(tg); 2589 AddIntegralAreaModifier(tg, label + TDash + tg.get_Name(), area, 0, ptCenter, ptCenter, false); 2590 addDTG(tg, area, csFactor, 2 * csFactor, ptCenter, ptCenter, metrics); 2591 break; 2592 case TacticalLines.FORT: 2593 case TacticalLines.ZONE: 2594 AddIntegralAreaModifier(tg, tg.get_Name(), area, 0, ptCenter, ptCenter, false); 2595 break; 2596 case TacticalLines.BDZ: 2597 AddIntegralAreaModifier(tg, label, area, 0, pt0, pt0, false); 2598 break; 2599 case TacticalLines.ASSAULT: 2600 case TacticalLines.ATKPOS: 2601 case TacticalLines.OBJ: 2602 case TacticalLines.NAI: 2603 case TacticalLines.TAI: 2604 case TacticalLines.BASE_CAMP_REVD: 2605 case TacticalLines.GUERILLA_BASE_REVD: 2606 case TacticalLines.ASSY: 2607 case TacticalLines.EA: 2608 case TacticalLines.DZ: 2609 case TacticalLines.EZ: 2610 case TacticalLines.LZ: 2611 case TacticalLines.PZ: 2612 case TacticalLines.AO: 2613 AddIntegralAreaModifier(tg, label + TSpace + tg.get_Name(), area, 0, ptCenter, ptCenter, false); 2614 break; 2615 case TacticalLines.BASE_CAMP: 2616 case TacticalLines.GUERILLA_BASE: 2617 AddIntegralAreaModifier(tg, label + TSpace + tg.get_Name(), area, -1 * csFactor, ptCenter, ptCenter, false); 2618 AddModifier(tg, tg.get_H(), area, 0, ptCenter, ptCenter); 2619 addDTG(tg, area, 1 * csFactor, 2 * csFactor, ptCenter, ptCenter, metrics); 2620 addNModifier(tg); 2621 addModifierBottomSegment(tg, tg.get_EchelonSymbol()); 2622 break; 2623 case TacticalLines.GENERIC_AREA: 2624 AddIntegralAreaModifier(tg, tg.get_H() + " " + tg.get_Name(), area, -0.5 * csFactor, ptCenter, ptCenter, false); 2625 addDTG(tg, area, 0.5 * csFactor, 1.5 * csFactor, ptCenter, ptCenter, metrics); 2626 addNModifier(tg); 2627 break; 2628 case TacticalLines.AIRHEAD: 2629 GetMBR(tg, ul, ur, lr, ll); 2630 AddIntegralAreaModifier(tg, label, aboveMiddle, csFactor, ll, lr, false); 2631 break; 2632 case TacticalLines.AC: 2633 case TacticalLines.LLTR: 2634 case TacticalLines.MRR: 2635 case TacticalLines.SL: 2636 case TacticalLines.TC: 2637 case TacticalLines.SAAFR: 2638 case TacticalLines.SC: 2639 AddIntegralModifier(tg, "Name: " + tg.get_Name(), aboveMiddle, -7 * csFactor, middleSegment, middleSegment + 1, false); 2640 AddIntegralModifier(tg, "Width: " + removeDecimal(tg.get_AM()), aboveMiddle, -6 * csFactor, middleSegment, middleSegment + 1, false); 2641 AddIntegralModifier(tg, "Min Alt: " + tg.get_X(), aboveMiddle, -5 * csFactor, middleSegment, middleSegment + 1, false); 2642 AddIntegralModifier(tg, "Max Alt: " + tg.get_X1(), aboveMiddle, -4 * csFactor, middleSegment, middleSegment + 1, false); 2643 AddIntegralModifier(tg, "DTG Start: " + tg.get_DTG(), aboveMiddle, -3 * csFactor, middleSegment, middleSegment + 1, false); 2644 AddIntegralModifier(tg, "DTG End: " + tg.get_DTG1(), aboveMiddle, -2 * csFactor, middleSegment, middleSegment + 1, false); 2645 AddIntegralModifier(tg, label + TSpace + tg.get_Name(), aboveMiddle, 0, middleSegment, middleSegment + 1, false); 2646 break; 2647 case TacticalLines.BEARING_J: 2648 case TacticalLines.BEARING_RDF: 2649 case TacticalLines.BEARING: 2650 case TacticalLines.ELECTRO: 2651 case TacticalLines.BEARING_EW: 2652 case TacticalLines.ACOUSTIC: 2653 case TacticalLines.ACOUSTIC_AMB: 2654 case TacticalLines.TORPEDO: 2655 case TacticalLines.OPTICAL: 2656 midPt = lineutility.MidPointDouble(pt0, pt1, 0); 2657 AddIntegralAreaModifier(tg, label, aboveMiddle, 0, midPt, midPt, true); 2658 pt3 = lineutility.ExtendDirectedLine(pt0, pt1, pt1, 3, font.getSize() / 2.0); 2659 AddIntegralAreaModifier(tg, tg.get_H(), aboveMiddle, 1, pt3, pt3, true); 2660 break; 2661 case TacticalLines.ACA: 2662 AddIntegralAreaModifier(tg, label + TSpace + tg.get_Name(), area, -3 * csFactor, ptCenter, ptCenter, false); 2663 AddIntegralAreaModifier(tg, tg.get_T1(), area, -2 * csFactor, ptCenter, ptCenter, false); 2664 AddIntegralAreaModifier(tg, "MIN ALT: " + tg.get_X(), area, -1 * csFactor, ptCenter, ptCenter, false, "H"); 2665 AddIntegralAreaModifier(tg, "MAX ALT: " + tg.get_X1(), area, 0, ptCenter, ptCenter, false, "H1"); 2666 AddIntegralAreaModifier(tg, "GRID " + tg.get_Location(), area, 1 * csFactor, ptCenter, ptCenter, false, "H2"); 2667 AddModifier2(tg, "EFF " + tg.get_DTG() + WDash, area, 2 * csFactor, ptCenter, ptCenter, false, "W"); 2668 AddModifier2(tg, tg.get_DTG1(), area, 3 * csFactor, ptCenter, ptCenter, false, "W1"); 2669 break; 2670 case TacticalLines.MFP: 2671 pt0 = tg.Pixels.get(middleSegment); 2672 pt1 = tg.Pixels.get(middleSegment + 1); 2673 AddIntegralModifier(tg, label, aboveMiddle, 0, middleSegment, middleSegment + 1, true); 2674 AddIntegralModifier(tg, tg.get_DTG() + WDash, aboveEnd, 1 * csFactor, 0, 1, false); 2675 AddIntegralModifier(tg, tg.get_DTG1(), aboveEnd, 2 * csFactor, 0, 1, false); 2676 break; 2677 case TacticalLines.LINTGT: 2678 AddIntegralModifier(tg, ap, aboveMiddle, -0.7 * csFactor, middleSegment, middleSegment + 1, false); 2679 break; 2680 case TacticalLines.LINTGTS: 2681 AddIntegralModifier(tg, ap, aboveMiddle, -0.7 * csFactor, middleSegment, middleSegment + 1, false); 2682 AddIntegralModifier(tg, label, aboveMiddle, 0.7 * csFactor, middleSegment, middleSegment + 1, false); 2683 break; 2684 case TacticalLines.FPF: 2685 AddIntegralModifier(tg, ap, aboveMiddle, -0.7 * csFactor, 0, 1, false); 2686 AddIntegralModifier(tg, label, aboveMiddle, .7 * csFactor, 0, 1, false); 2687 AddIntegralModifier(tg, tg.get_T1(), aboveMiddle, 1.7 * csFactor, 0, 1, false); 2688 AddIntegralModifier(tg, v, aboveMiddle, 2.7 * csFactor, 0, 1, false); 2689 break; 2690 case TacticalLines.AT: 2691 AddIntegralAreaModifier(tg, ap, area, 0, ptCenter, ptCenter, false); 2692 break; 2693 case TacticalLines.RECTANGULAR: 2694 case TacticalLines.CIRCULAR: 2695 AddIntegralAreaModifier(tg, ap, area, 0, pt0, pt0, false); 2696 break; 2697 case TacticalLines.PBS_CIRCLE: 2698 case TacticalLines.PBS_ELLIPSE: 2699 case TacticalLines.PBS_RECTANGLE: 2700 case TacticalLines.BBS_POINT: 2701 AddIntegralAreaModifier(tg, tg.get_Name(), area, 0, pt0, pt0, false); 2702 break; 2703 case TacticalLines.RECTANGULAR_TARGET: 2704 stringWidth = metrics.stringWidth(tg.get_Name()); 2705 POINT2 offsetCenterPoint = new POINT2(ptCenter.x + ((double) stringWidth) / 2.0, ptCenter.y); 2706 AddIntegralAreaModifier(tg, tg.get_Name(), area, -1 * csFactor, offsetCenterPoint, offsetCenterPoint, false); 2707 break; 2708 case TacticalLines.SMOKE: 2709 AddIntegralAreaModifier(tg, ap, area, -csFactor, ptCenter, ptCenter, false); 2710 AddIntegralAreaModifier(tg, label, area, 0, ptCenter, ptCenter, false); 2711 addDTG(tg, area, 1 * csFactor, 2 * csFactor, ptCenter, ptCenter, metrics); 2712 break; 2713 case TacticalLines.LINE: 2714 AddIntegralModifier(tg, tg.get_Name(), aboveMiddle, csFactor, middleSegment, middleSegment + 1, false); 2715 break; 2716 case TacticalLines.MINED: 2717 if (tg.isHostile()) { 2718 pt1 = lineutility.MidPointDouble(pt0, pt1, 0); 2719 AddIntegralAreaModifier(tg, tg.get_N(), aboveMiddle, 0, pt0, pt1, true); 2720 if (middleSegment != 0) { 2721 pt0 = tg.Pixels.get(middleSegment); 2722 pt1 = tg.Pixels.get(middleSegment + 1); 2723 pt1 = lineutility.MidPointDouble(pt0, pt1, 0); 2724 AddIntegralAreaModifier(tg, tg.get_N(), aboveMiddle, 0, pt0, pt1, true); 2725 } 2726 } 2727 GetMBR(tg, ul, ur, lr, ll); 2728 AddIntegralAreaModifier(tg, tg.get_H(), aboveMiddle, -1.5 * csFactor, ul, ur, false); 2729 AddIntegralAreaModifier(tg, tg.get_DTG(), aboveMiddle, 1.5 * csFactor, ll, lr, false); 2730 addModifierOnLine("M", tg); 2731 AddIntegralAreaModifier(tg, getImageModifier(tg), areaImage, 0, ptCenter, ptCenter, false); 2732 break; 2733 case TacticalLines.FENCED: 2734 if (tg.isHostile()) { 2735 pt1 = lineutility.MidPointDouble(pt0, pt1, 0); 2736 AddIntegralAreaModifier(tg, tg.get_N(), aboveMiddle, 0, pt0, pt1, true); 2737 if (middleSegment != 0) { 2738 pt0 = tg.Pixels.get(middleSegment); 2739 pt1 = tg.Pixels.get(middleSegment + 1); 2740 pt1 = lineutility.MidPointDouble(pt0, pt1, 0); 2741 AddIntegralAreaModifier(tg, tg.get_N(), aboveMiddle, 0, pt0, pt1, true); 2742 } 2743 } 2744 addModifierOnLine("M", tg); 2745 AddIntegralAreaModifier(tg, getImageModifier(tg), areaImage, 0, ptCenter, ptCenter, false); 2746 break; 2747 case TacticalLines.ASLTXING: 2748 if (tg.Pixels.get(1).y > tg.Pixels.get(0).y) { 2749 pt0 = tg.Pixels.get(1); 2750 pt1 = tg.Pixels.get(3); 2751 pt2 = tg.Pixels.get(0); 2752 pt3 = tg.Pixels.get(2); 2753 } else { 2754 pt0 = tg.Pixels.get(0); 2755 pt1 = tg.Pixels.get(2); 2756 pt2 = tg.Pixels.get(1); 2757 pt3 = tg.Pixels.get(3); 2758 } 2759 pt2 = lineutility.ExtendAlongLineDouble2(pt0, pt2, -20); 2760 pt3 = lineutility.ExtendAlongLineDouble2(pt1, pt3, -20); 2761 addDTG(tg, aboveMiddle, 0, csFactor, pt2, pt3, metrics); 2762 break; 2763 case TacticalLines.SERIES: 2764 case TacticalLines.DRCL: 2765 addModifierTopSegment(tg, tg.get_Name()); 2766 break; 2767 case TacticalLines.STRIKWARN: 2768 AddIntegralModifier(tg, "1", aboveMiddle, 0, index, index + 1, true); 2769 AddIntegralModifier(tg, "2", aboveMiddle, 0, size/2, size/2 + 1, true); 2770 break; 2771 case TacticalLines.SCREEN: 2772 case TacticalLines.COVER: 2773 case TacticalLines.GUARD: 2774 if (tg.Pixels.size() == 4) { 2775 pt1 = new POINT2(tg.Pixels.get(1)); 2776 pt2 = new POINT2(tg.Pixels.get(2)); 2777 AddIntegralAreaModifier(tg, label, area, 0, pt1, pt1, true); 2778 AddIntegralAreaModifier(tg, label, area, 0, pt2, pt2, true); 2779 } else { 2780 stringHeight = (int) (0.5 * (double) font.getSize()); 2781 dAngle0 = Math.atan2(tg.Pixels.get(0).y - tg.Pixels.get(1).y, tg.Pixels.get(0).x - tg.Pixels.get(1).x); 2782 dAngle1 = Math.atan2(tg.Pixels.get(0).y - tg.Pixels.get(2).y, tg.Pixels.get(0).x - tg.Pixels.get(2).x); 2783 pt0 = new POINT2(tg.Pixels.get(0)); 2784 pt0.x -= 30 * Math.cos(dAngle0); 2785 pt0.y -= 30 * Math.sin(dAngle0) + stringHeight; 2786 pt1 = new POINT2(tg.Pixels.get(0)); 2787 pt1.x -= 30 * Math.cos(dAngle1); 2788 pt1.y -= 30 * Math.sin(dAngle1) + stringHeight; 2789 AddIntegralAreaModifier(tg, label, area, 0, pt0, pt0, true); 2790 AddIntegralAreaModifier(tg, label, area, 0, pt1, pt1, true); 2791 } 2792 break; 2793 case TacticalLines.MSR_ONEWAY: 2794 case TacticalLines.ASR_ONEWAY: 2795 case TacticalLines.TRAFFIC_ROUTE_ONEWAY: 2796 case TacticalLines.MSR_TWOWAY: 2797 case TacticalLines.ASR_TWOWAY: 2798 case TacticalLines.MSR_ALT: 2799 case TacticalLines.ASR_ALT: 2800 case TacticalLines.TRAFFIC_ROUTE_ALT: 2801 stringWidth = (int) (1.5 * (double) metrics.stringWidth(label + TSpace + tg.get_Name())); 2802 double arrowOffset = 10 * DPIScaleFactor; 2803 if (linetype == TacticalLines.MSR_TWOWAY || linetype == TacticalLines.ASR_TWOWAY) 2804 arrowOffset = 25 * DPIScaleFactor; 2805 boolean isAlt = linetype == TacticalLines.MSR_ALT || linetype == TacticalLines.ASR_ALT || linetype == TacticalLines.TRAFFIC_ROUTE_ALT; 2806 if (isAlt) { 2807 stringWidth2 = (int) (1.5 * (double) metrics.stringWidth("ALT")); 2808 if (stringWidth2 > stringWidth) { 2809 stringWidth = stringWidth2; 2810 } 2811 } 2812 2813 foundSegment = false; 2814 //acevedo - 11/30/2017 - adding option to render only 2 labels. 2815 if (RendererSettings.getInstance().getTwoLabelOnly() == false) { 2816 for (j = 0; j < tg.Pixels.size() - 1; j++) { 2817 pt0 = tg.Pixels.get(j); 2818 pt1 = tg.Pixels.get(j + 1); 2819 dist = lineutility.CalcDistanceDouble(pt0, pt1); 2820 int arrowSide = arraysupport.SupplyRouteArrowSide(pt0, pt1); 2821 if (dist < stringWidth) { 2822 continue; 2823 } else { 2824 if (arrowSide == 1 || arrowSide == 2) { 2825 // Shift points to account for arrow shift with DPI 2826 pt0 = lineutility.ExtendDirectedLine(pt1, pt0, pt0, arrowSide, arrowOffset); 2827 pt1 = lineutility.ExtendDirectedLine(pt1, pt0, pt1, arrowSide, arrowOffset); 2828 AddModifier(tg, label + TSpace + tg.get_Name(), aboveMiddle, -1.7 * csFactor, pt0, pt1); 2829 if (isAlt) 2830 AddModifier(tg, "ALT", aboveMiddle, 0, pt0, pt1); 2831 } else { 2832 AddModifier(tg, label + TSpace + tg.get_Name(), aboveMiddle, -0.7 * csFactor, pt0, pt1); 2833 if (isAlt) { 2834 pt0 = lineutility.ExtendDirectedLine(pt1, pt0, pt0, arrowSide, arrowOffset); 2835 pt1 = lineutility.ExtendDirectedLine(pt1, pt0, pt1, arrowSide, arrowOffset); 2836 AddModifier(tg, "ALT", aboveMiddle, 0, pt0, pt1); 2837 } 2838 } 2839 foundSegment = true; 2840 } 2841 } 2842 if (foundSegment == false) { 2843 pt0 = tg.Pixels.get(middleSegment); 2844 pt1 = tg.Pixels.get(middleSegment + 1); 2845 int arrowSide = arraysupport.SupplyRouteArrowSide(pt0, pt1); 2846 if (arrowSide == 1 || arrowSide == 2) { 2847 // Shift points to account for arrow shift with DPI 2848 pt0 = lineutility.ExtendDirectedLine(pt1, pt0, pt0, arrowSide, arrowOffset); 2849 pt1 = lineutility.ExtendDirectedLine(pt1, pt0, pt1, arrowSide, arrowOffset); 2850 AddModifier(tg, label + TSpace + tg.get_Name(), aboveMiddle, -1.7 * csFactor, pt0, pt1); 2851 if (isAlt) 2852 AddModifier(tg, "ALT", aboveMiddle, 0, pt0, pt1); 2853 } else { 2854 AddModifier(tg, label + TSpace + tg.get_Name(), aboveMiddle, -0.7 * csFactor, pt0, pt1); 2855 if (isAlt) { 2856 pt0 = lineutility.ExtendDirectedLine(pt1, pt0, pt0, arrowSide, arrowOffset); 2857 pt1 = lineutility.ExtendDirectedLine(pt1, pt0, pt1, arrowSide, arrowOffset); 2858 AddModifier(tg, "ALT", aboveMiddle, 0, pt0, pt1); 2859 } 2860 } 2861 } 2862 } 2863 else { 2864 // 2 labels one to the north and the other to the south of graphic. 2865 northestPtIndex = 0; 2866 northestPt = tg.Pixels.get(northestPtIndex); 2867 southestPtIndex = 0; 2868 southestPt = tg.Pixels.get(southestPtIndex); 2869 2870 for (j = 0; j < tg.Pixels.size() - 1; j++) { 2871 pt0 = tg.Pixels.get(j); 2872 if (pt0.y >= northestPt.y) { 2873 northestPt = pt0; 2874 northestPtIndex = j; 2875 } 2876 if (pt0.y <= southestPt.y) { 2877 southestPt = pt0; 2878 southestPtIndex = j; 2879 } 2880 } 2881 2882 AddIntegralModifier(tg, label + TSpace + tg.get_Name(), aboveMiddle, -1.7 * csFactor, northestPtIndex, northestPtIndex + 1, false); 2883 if (isAlt) 2884 AddIntegralModifier(tg, "ALT", aboveMiddle, -0.7 * csFactor, northestPtIndex, northestPtIndex + 1, false); 2885 2886 if (northestPtIndex != southestPtIndex) { 2887 AddIntegralModifier(tg, label + TSpace + tg.get_Name(), aboveMiddle, -1.7 * csFactor, southestPtIndex, southestPtIndex + 1, false); 2888 if (isAlt) 2889 AddIntegralModifier(tg, "ALT", aboveMiddle, -0.7 * csFactor, southestPtIndex, southestPtIndex + 1, false); 2890 } 2891 }//else 2892 break; 2893 case TacticalLines.DHA_REVD: 2894 AddIntegralAreaModifier(tg, "DETAINEE", area, -1.5 * csFactor, ptCenter, ptCenter, false); 2895 AddIntegralAreaModifier(tg, "HOLDING", area, -0.5 * csFactor, ptCenter, ptCenter, false); 2896 AddIntegralAreaModifier(tg, "AREA", area, 0.5 * csFactor, ptCenter, ptCenter, false); 2897 AddIntegralAreaModifier(tg, tg.get_Name(), area, 1.5 * csFactor, ptCenter, ptCenter, false); 2898 break; 2899 case TacticalLines.EPW: 2900 AddIntegralAreaModifier(tg, "EPW", area, -1.5 * csFactor, ptCenter, ptCenter, false); 2901 AddIntegralAreaModifier(tg, "HOLDING", area, -0.5 * csFactor, ptCenter, ptCenter, false); 2902 AddIntegralAreaModifier(tg, "AREA", area, 0.5 * csFactor, ptCenter, ptCenter, false); 2903 AddIntegralAreaModifier(tg, tg.get_Name(), area, 1.5 * csFactor, ptCenter, ptCenter, false); 2904 break; 2905 case TacticalLines.UXO: 2906 addModifierOnLine("UXO", tg, true); 2907 break; 2908 case TacticalLines.GENERAL: 2909 addNModifier(tg); 2910 break; 2911 case TacticalLines.DHA: 2912 case TacticalLines.KILL_ZONE: 2913 case TacticalLines.FARP: 2914 AddIntegralAreaModifier(tg, label, area, -0.5 * csFactor, ptCenter, ptCenter, false); 2915 AddIntegralAreaModifier(tg, tg.get_Name(), area, 0.5 * csFactor, ptCenter, ptCenter, false); 2916 break; 2917 case TacticalLines.BSA: 2918 case TacticalLines.DSA: 2919 case TacticalLines.CSA: 2920 case TacticalLines.RSA: 2921 AddIntegralAreaModifier(tg, label, area, 0, ptCenter, ptCenter, false); 2922 break; 2923 case TacticalLines.RHA: 2924 AddIntegralAreaModifier(tg, "REFUGEE", area, -1.5 * csFactor, ptCenter, ptCenter, false); 2925 AddIntegralAreaModifier(tg, "HOLDING", area, -0.5 * csFactor, ptCenter, ptCenter, false); 2926 AddIntegralAreaModifier(tg, "AREA", area, 0.5 * csFactor, ptCenter, ptCenter, false); 2927 AddIntegralAreaModifier(tg, tg.get_Name(), area, 1.5 * csFactor, ptCenter, ptCenter, false); 2928 break; 2929 case TacticalLines.MSR: 2930 case TacticalLines.ASR: 2931 case TacticalLines.TRAFFIC_ROUTE: 2932 //AddIntegralModifier(tg, label + tg.get_Name(), aboveMiddle, -1*csFactor, middleSegment, middleSegment + 1,false); 2933 foundSegment = false; 2934 //acevedo - 11/30/2017 - adding option to render only 2 labels. 2935 if (RendererSettings.getInstance().getTwoLabelOnly() == false) { 2936 for (j = 0; j < tg.Pixels.size() - 1; j++) { 2937 pt0 = tg.Pixels.get(j); 2938 pt1 = tg.Pixels.get(j + 1); 2939 stringWidth = (int) (1.5 * (double) metrics.stringWidth(label + TSpace + tg.get_Name())); 2940 dist = lineutility.CalcDistanceDouble(pt0, pt1); 2941 if (dist < stringWidth) { 2942 continue; 2943 } else { 2944 AddIntegralModifier(tg, label + TSpace + tg.get_Name(), aboveMiddle, -1 * csFactor, j, j + 1, false); 2945 foundSegment = true; 2946 } 2947 } 2948 if (foundSegment == false) { 2949 AddIntegralModifier(tg, label + TSpace + tg.get_Name(), aboveMiddle, -1 * csFactor, middleSegment, middleSegment + 1, false); 2950 } 2951 } 2952 else { 2953 // 2 labels one to the north and the other to the south of graphic. 2954 for (j = 0; j < tg.Pixels.size() ; j++) { 2955 pt0 = tg.Pixels.get(j); 2956 2957 if (northestPt == null) 2958 { 2959 northestPt = pt0; 2960 northestPtIndex = j; 2961 } 2962 if (southestPt == null) 2963 { 2964 southestPt = pt0; 2965 southestPtIndex = j; 2966 } 2967 if (pt0.y >= northestPt.y) 2968 { 2969 northestPt = pt0; 2970 northestPtIndex = j; 2971 } 2972 2973 if (pt0.y <= southestPt.y) 2974 { 2975 southestPt = pt0; 2976 southestPtIndex = j; 2977 } 2978 }//for 2979 middleSegment = northestPtIndex; 2980 middleSegment2 = southestPtIndex; 2981 2982 if (middleSegment == tg.Pixels.size() -1) { 2983 middleSegment-=1; 2984 } 2985 if (middleSegment2 == tg.Pixels.size() -1) { 2986 middleSegment2-=1; 2987 } 2988 if (middleSegment == middleSegment2) { 2989 middleSegment2-=1; 2990 } 2991 2992 // if (middleSegment != middleSegment2) { 2993 AddIntegralModifier(tg, label + TSpace + tg.get_Name(), aboveMiddle, 0, middleSegment, middleSegment + 1, false); 2994 //} 2995 AddIntegralModifier(tg, label + TSpace + tg.get_Name(), aboveMiddle, 0, middleSegment2, middleSegment2 + 1, false); 2996 2997 }//else 2998 break; 2999 case TacticalLines.TRIP: 3000 foundSegment = false; 3001 stringWidth = (int) (1.5 * (double) metrics.stringWidth(label)); 3002 for (j = 0; j < tg.Pixels.size() - 1; j++) { 3003 pt0 = tg.Pixels.get(j); 3004 pt1 = tg.Pixels.get(j + 1); 3005 midPt = lineutility.MidPointDouble(pt0, pt1, 0); 3006 dist = lineutility.CalcDistanceDouble(pt0, pt1); 3007 if (dist > stringWidth) { 3008 AddModifier2(tg, label, aboveMiddle, -0.7 * csFactor, midPt, midPt, false); 3009 foundSegment = true; 3010 } 3011 } 3012 if (!foundSegment) { 3013 midPt = lineutility.MidPointDouble(tg.Pixels.get(middleSegment), tg.Pixels.get(middleSegment + 1), 0); 3014 AddModifier2(tg, label, aboveMiddle, -0.7 * csFactor, midPt, midPt, false); 3015 } 3016 break; 3017 case TacticalLines.GAP: 3018 if (tg.Pixels.get(1).y > tg.Pixels.get(0).y) { 3019 pt0 = tg.Pixels.get(1); 3020 pt1 = tg.Pixels.get(3); 3021 pt2 = tg.Pixels.get(0); 3022 pt3 = tg.Pixels.get(2); 3023 } else { 3024 pt0 = tg.Pixels.get(0); 3025 pt1 = tg.Pixels.get(2); 3026 pt2 = tg.Pixels.get(1); 3027 pt3 = tg.Pixels.get(3); 3028 } 3029 pt2 = lineutility.ExtendAlongLineDouble2(pt0, pt2, -20); 3030 pt3 = lineutility.ExtendAlongLineDouble2(pt1, pt3, -20); 3031 AddIntegralAreaModifier(tg, tg.get_Name(), aboveMiddle, 0, pt0, pt1, false); 3032 addDTG(tg, aboveMiddle, 0, csFactor, pt2, pt3, metrics); 3033 break; 3034 case TacticalLines.BIO: 3035 case TacticalLines.BIOT: 3036 case TacticalLines.CHEM: 3037 case TacticalLines.CHEMT: 3038 case TacticalLines.NUC: 3039 case TacticalLines.RAD: 3040 case TacticalLines.RADT: 3041 AddIntegralAreaModifier(tg, getImageModifier(tg), areaImage, 0, ptCenter, ptCenter, false); 3042 break; 3043 case TacticalLines.ANCHORAGE_LINE: 3044 AddIntegralAreaModifier(tg, getImageModifier(tg), aboveMiddle, -0.15 * csFactor, tg.Pixels.get(middleSegment), tg.Pixels.get(middleSegment+1), false); 3045 break; 3046 case TacticalLines.ANCHORAGE_AREA: 3047 // Add anchor on segment with lowest midpoint 3048 y = pt0.y + pt1.y; 3049 index = 0; 3050 for (j = 1; j < size - 1; j++) { 3051 if (y < tg.Pixels.get(j).y + tg.Pixels.get(j + 1).y) { 3052 index = j; 3053 y = tg.Pixels.get(index).y + tg.Pixels.get(index + 1).y; 3054 } 3055 } 3056 AddIntegralAreaModifier(tg, getImageModifier(tg), aboveMiddle, -0.25 * csFactor, tg.Pixels.get(index), tg.Pixels.get(index + 1), false); 3057 break; 3058 case TacticalLines.MINE_LINE: 3059 AddIntegralAreaModifier(tg, getImageModifier(tg), aboveMiddle, -0.2 * csFactor, tg.Pixels.get(middleSegment), tg.Pixels.get(middleSegment + 1), false); 3060 if (tg.isHostile()) { 3061 AddIntegralAreaModifier(tg, tg.get_N(), toEnd, 0.0, pt0, pt1, false); 3062 AddIntegralAreaModifier(tg, tg.get_N(), toEnd, 0.0, ptLast, ptNextToLast, false); 3063 } 3064 break; 3065 case TacticalLines.DEPICT: 3066 GetMBR(tg, ul, ur, lr, ll); 3067 addNModifier(tg); 3068 AddIntegralAreaModifier(tg, getImageModifier(tg), areaImage, 0, ptCenter, ptCenter, false); 3069 break; 3070 case TacticalLines.FFA: 3071 case TacticalLines.RFA: 3072 case TacticalLines.NFA: 3073 AddIntegralAreaModifier(tg, label, area, -1 * csFactor, ptCenter, ptCenter, false); 3074 AddIntegralAreaModifier(tg, tg.get_Name(), area, 0, ptCenter, ptCenter, false); 3075 addDTG(tg, area, 1 * csFactor, 2 * csFactor, ptCenter, ptCenter, metrics); 3076 break; 3077 case TacticalLines.PAA: 3078 addModifierOnLine("PAA", tg); 3079 AddIntegralAreaModifier(tg, tg.get_Name(), area, -0.5 * csFactor, ptCenter, ptCenter, false); 3080 addDTG(tg, area, 0.5 * csFactor, 1.5 * csFactor, ptCenter, ptCenter, metrics); 3081 break; 3082 case TacticalLines.FSA: 3083 AddIntegralAreaModifier(tg, label + TSpace + tg.get_Name(), area, -0.5 * csFactor, ptCenter, ptCenter, false); 3084 addDTG(tg, area, 0.5 * csFactor, 1.5 * csFactor, ptCenter, ptCenter, metrics); 3085 break; 3086 case TacticalLines.ATI: 3087 case TacticalLines.CFFZ: 3088 case TacticalLines.CFZ: 3089 case TacticalLines.TBA: 3090 case TacticalLines.TVAR: 3091 case TacticalLines.ZOR: 3092 case TacticalLines.DA: 3093 case TacticalLines.SENSOR: 3094 case TacticalLines.CENSOR: 3095 case TacticalLines.KILLBOXBLUE: 3096 case TacticalLines.KILLBOXPURPLE: 3097 AddIntegralAreaModifier(tg, label, area, -0.5 * csFactor, ptCenter, ptCenter, false); 3098 AddIntegralAreaModifier(tg, tg.get_Name(), area, 0.5 * csFactor, ptCenter, ptCenter, false); 3099 GetMBR(tg, ul, ur, lr, ll); 3100 POINT2 ptLeft = ul; 3101 POINT2 ptRight = ur; 3102 if (tg.get_Client().equalsIgnoreCase("ge")) { 3103 ptLeft.x -= font.getSize() / 2; 3104 ptRight.x -= font.getSize() / 2; 3105 } 3106 AddIntegralAreaModifier(tg, tg.get_DTG() + WDash, toEnd, 0.5 * csFactor, ptLeft, ptRight, false, "W"); 3107 AddIntegralAreaModifier(tg, tg.get_DTG1(), toEnd, 1.5 * csFactor, ptLeft, ptRight, false, "W1"); 3108 break; 3109 case TacticalLines.BATTLE: 3110 case TacticalLines.STRONG: 3111 AddIntegralAreaModifier(tg, tg.get_Name(), area, 0, ptCenter, ptCenter, false); 3112 addModifierBottomSegment(tg, tg.get_EchelonSymbol()); 3113 break; 3114 case TacticalLines.PNO: 3115 AddIntegralAreaModifier(tg, label + TSpace + tg.get_Name(), area, 0, ptCenter, ptCenter, false); 3116 addModifierBottomSegment(tg, tg.get_EchelonSymbol()); 3117 addNModifier(tg); 3118 break; 3119 case TacticalLines.WFZ_REVD: 3120 AddIntegralAreaModifier(tg, label, area, -1.5 * csFactor, ptCenter, ptCenter, true); 3121 AddIntegralAreaModifier(tg, tg.get_Name(), area, -0.5 * csFactor, ptCenter, ptCenter, true); 3122 AddIntegralAreaModifier(tg, "TIME FROM: " + tg.get_DTG(), area, 0.5 * csFactor, ptCenter, ptCenter, true, "W"); 3123 AddIntegralAreaModifier(tg, "TIME TO: " + tg.get_DTG1(), area, 1.5 * csFactor, ptCenter, ptCenter, true, "W1"); 3124 break; 3125 case TacticalLines.WFZ: 3126 AddIntegralAreaModifier(tg, label, area, -2.5 * csFactor, ptCenter, ptCenter, true); 3127 AddIntegralAreaModifier(tg, tg.get_Name(), area, -1.5 * csFactor, ptCenter, ptCenter, true); 3128 AddIntegralAreaModifier(tg, "TIME FROM: " + tg.get_DTG(), area, -0.5 * csFactor, ptCenter, ptCenter, true, "W"); 3129 AddIntegralAreaModifier(tg, "TIME TO: " + tg.get_DTG1(), area, 0.5 * csFactor, ptCenter, ptCenter, true, "W1"); 3130 AddIntegralAreaModifier(tg, "MIN ALT: " + tg.get_X(), area, 1.5 * csFactor, ptCenter, ptCenter, false, "H"); 3131 AddIntegralAreaModifier(tg, "MAX ALT: " + tg.get_X1(), area, 2.5, ptCenter, ptCenter, false, "H1"); 3132 break; 3133 case TacticalLines.OBSFAREA: 3134 AddIntegralAreaModifier(tg, label, area, -1.5 * csFactor, ptCenter, ptCenter, false); 3135 AddIntegralAreaModifier(tg, tg.get_Name(), area, -0.5 * csFactor, ptCenter, ptCenter, false); 3136 AddIntegralAreaModifier(tg, tg.get_DTG() + WDash, area, 0.5 * csFactor, ptCenter, ptCenter, false, "W"); 3137 AddIntegralAreaModifier(tg, tg.get_DTG1(), area, 1.5 * csFactor, ptCenter, ptCenter, false, "W1"); 3138 break; 3139 case TacticalLines.OBSAREA: 3140 AddIntegralAreaModifier(tg, tg.get_Name(), area, -1 * csFactor, ptCenter, ptCenter, true); 3141 AddIntegralAreaModifier(tg, tg.get_DTG() + WDash, area, 0, ptCenter, ptCenter, true, "W"); 3142 AddIntegralAreaModifier(tg, tg.get_DTG1(), area, 1 * csFactor, ptCenter, ptCenter, true, "W1"); 3143 break; 3144 case TacticalLines.ROZ: 3145 case TacticalLines.AARROZ: 3146 case TacticalLines.UAROZ: 3147 case TacticalLines.WEZ: 3148 case TacticalLines.FEZ: 3149 case TacticalLines.JEZ: 3150 case TacticalLines.FAADZ: 3151 case TacticalLines.HIDACZ: 3152 case TacticalLines.MEZ: 3153 case TacticalLines.LOMEZ: 3154 case TacticalLines.HIMEZ: 3155 AddIntegralAreaModifier(tg, label, area, -2.5, ptCenter, ptCenter, false, ""); 3156 AddIntegralAreaModifier(tg, tg.get_Name(), area, -1.5, ptCenter, ptCenter, false, "T"); 3157 AddIntegralAreaModifier(tg, "MIN ALT: " + tg.get_X(), area, -0.5, ptCenter, ptCenter, false, "H"); 3158 AddIntegralAreaModifier(tg, "MAX ALT: " + tg.get_X1(), area, 0.5, ptCenter, ptCenter, false, "H1"); 3159 AddIntegralAreaModifier(tg, "TIME FROM: " + tg.get_DTG(), area, 1.5, ptCenter, ptCenter, false, "W"); 3160 AddIntegralAreaModifier(tg, "TIME TO: " + tg.get_DTG1(), area, 2.5, ptCenter, ptCenter, false, "W1"); 3161 break; 3162 case TacticalLines.ENCIRCLE: 3163 if (tg.isHostile()) { 3164 AddIntegralModifier(tg, tg.get_N(), aboveMiddle, 0, 0, 1, true); 3165 AddIntegralModifier(tg, tg.get_N(), aboveMiddle, 0, middleSegment, middleSegment + 1, true); 3166 } 3167 break; 3168 case TacticalLines.LAA: 3169 AddIntegralAreaModifier(tg, getImageModifier(tg), areaImage, 0, ptCenter, ptCenter, false); 3170 AddIntegralAreaModifier(tg, label, area, -1 * csFactor, ptCenter, ptCenter, false); 3171 break; 3172 case TacticalLines.BOUNDARY: 3173 if (clipRect != null) { 3174 AddBoundaryModifiers(tg, g2d, clipRect); 3175 } else { 3176 AddBoundaryModifiers(tg, g2d, clipArray); 3177 } 3178 break; 3179 case TacticalLines.CFL: 3180 stringWidth = (int) ((double) metrics.stringWidth(label + TSpace + tg.get_Name())); 3181 stringWidth2 = (int) ((double) metrics.stringWidth(tg.get_DTG() + WDash + tg.get_DTG1())); 3182 if (stringWidth2 > stringWidth) { 3183 stringWidth = stringWidth2; 3184 } 3185 pt0 = new POINT2(tg.Pixels.get(middleSegment)); 3186 pt1 = new POINT2(tg.Pixels.get(middleSegment + 1)); 3187 getPixelsMiddleSegment(tg, stringWidth, pt0, pt1); 3188 AddModifier2(tg, label + TSpace + tg.get_Name(), aboveMiddle, -0.7 * csFactor, pt0, pt1, false); 3189 addDTG(tg, aboveMiddle, 0.7 * csFactor, 1.7 * csFactor, pt0, pt1, metrics); 3190 break; 3191 case TacticalLines.FLOT: 3192 if (tg.get_H().equals("1")) { 3193 label = "LC"; 3194 } else if (tg.get_H().equals("2")) { 3195 label = ""; 3196 } 3197 AddIntegralAreaModifier(tg, label, toEnd, 0, pt0, pt1, false); 3198 AddIntegralAreaModifier(tg, label, toEnd, 0, ptLast, ptNextToLast, false); 3199 3200 if (tg.isHostile()) { 3201 AddIntegralAreaModifier(tg, tg.get_N(), toEnd, -1 * csFactor, pt0, pt1, false); 3202 AddIntegralAreaModifier(tg, tg.get_N(), toEnd, -1 * csFactor, ptLast, ptNextToLast, false); 3203 } 3204 break; 3205 case TacticalLines.LC: 3206 double shiftFactor = 1d; 3207 if (shiftLines) { 3208 shiftFactor = 0.5d; 3209 } 3210 if (tg.isHostile()) { 3211 if (pt0.x < pt1.x) { 3212 TLineFactor = -shiftFactor;//was -1 3213 } else { 3214 TLineFactor = shiftFactor;//was 1 3215 } 3216 AddIntegralAreaModifier(tg, tg.get_N(), toEnd, TLineFactor, pt0, pt1, false); 3217 if (ptNextToLast.x < ptLast.x) { 3218 TLineFactor = -shiftFactor;//was -1 3219 } else { 3220 TLineFactor = shiftFactor;//was 1 3221 } 3222 AddIntegralAreaModifier(tg, tg.get_N(), toEnd, TLineFactor, ptLast, ptNextToLast, false); 3223 } 3224 AddIntegralAreaModifier(tg, label, toEnd, 0, pt0, pt1, false); 3225 AddIntegralAreaModifier(tg, label, toEnd, 0, ptLast, ptNextToLast, false); 3226 break; 3227 case TacticalLines.CATK: 3228 AddIntegralModifier(tg, label, aboveMiddle, 0, 1, 0, false); 3229 break; 3230 case TacticalLines.CATKBYFIRE: 3231 stringWidth = (int) (1.5 * (double) metrics.stringWidth(label)); 3232 pt2 = lineutility.ExtendAlongLineDouble(pt0, pt1, stringWidth); 3233 AddModifier2(tg, label, aboveMiddle, 0, pt1, pt2, false); 3234 break; 3235 case TacticalLines.IL: 3236 AddIntegralModifier(tg, tg.get_Name(), aboveMiddle, 0, 1, 0, false); 3237 break; 3238 case TacticalLines.RETIRE: 3239 case TacticalLines.PURSUIT: 3240 case TacticalLines.WITHDRAW: 3241 case TacticalLines.DISENGAGE: 3242 case TacticalLines.WDRAWUP: 3243 case TacticalLines.FPOL: 3244 case TacticalLines.RPOL: 3245 case TacticalLines.DEMONSTRATE: 3246 AddIntegralModifier(tg, label, aboveMiddle, 0, 0, 1, true); 3247 break; 3248 case TacticalLines.RIP: 3249 case TacticalLines.BOMB: 3250 case TacticalLines.TGMF: 3251 AddIntegralAreaModifier(tg, label, area, 0, ptCenter, ptCenter, true); 3252 break; 3253 case TacticalLines.MSDZ: 3254 AddIntegralAreaModifier(tg, "1", area, 0, pt1, pt1, true); 3255 AddIntegralAreaModifier(tg, "2", area, 0, pt2, pt2, true); 3256 AddIntegralAreaModifier(tg, "3", area, 0, pt3, pt3, true); 3257 break; 3258 case TacticalLines.DELAY: 3259 AddIntegralModifier(tg, tg.get_DTG(), aboveMiddle, -1 * csFactor, 0, 1, false); 3260 AddIntegralModifier(tg, label, aboveMiddle, 0, 0, 1, true); 3261 break; 3262 case TacticalLines.GENERIC_LINE: 3263 pt0 = tg.Pixels.get(0); 3264 pt1 = tg.Pixels.get(1); 3265 pt2 = tg.Pixels.get(tg.Pixels.size() - 1); 3266 pt3 = tg.Pixels.get(tg.Pixels.size() - 2); 3267 dist = lineutility.CalcDistanceDouble(pt0, pt1); 3268 dist2 = lineutility.CalcDistanceDouble(pt2, pt3); 3269 stringWidth = (int) ((double) metrics.stringWidth(tg.get_H() + " " + tg.get_Name())); 3270 stringWidth2 = (int) ((double) metrics.stringWidth(tg.get_DTG())); 3271 if (stringWidth2 > stringWidth) { 3272 stringWidth = stringWidth2; 3273 } 3274 3275 if (tg.Pixels.size() == 2) //one segment 3276 { 3277 pt1 = lineutility.ExtendAlongLineDouble(pt0, pt1, stringWidth); 3278 AddModifier2(tg, tg.get_H() + " " + tg.get_Name(), aboveMiddle, -0.7 * csFactor, pt0, pt1, false); 3279 AddModifier2(tg, tg.get_DTG() + WDash, aboveMiddle, 0.7 * csFactor, pt0, pt1, false); 3280 AddModifier2(tg, tg.get_DTG1(), aboveMiddle, 1.7 * csFactor, pt0, pt1, false); 3281 if (dist > 3.5 * stringWidth)//was 28stringwidth+5 3282 { 3283 pt0 = tg.Pixels.get(tg.Pixels.size() - 1); 3284 pt1 = tg.Pixels.get(tg.Pixels.size() - 2); 3285 pt1 = lineutility.ExtendAlongLineDouble(pt0, pt1, stringWidth); 3286 AddModifier2(tg, tg.get_H() + " " + tg.get_Name(), aboveMiddle, -0.7 * csFactor, pt0, pt1, false); 3287 AddModifier2(tg, tg.get_DTG() + WDash, aboveMiddle, 0.7 * csFactor, pt0, pt1, false); 3288 AddModifier2(tg, tg.get_DTG1(), aboveMiddle, 1.7 * csFactor, pt0, pt1, false); 3289 } 3290 } else //more than one semgent 3291 { 3292 double dist3 = lineutility.CalcDistanceDouble(pt0, pt2); 3293 if (dist > stringWidth + 5 || dist >= dist2 || dist3 > stringWidth + 5) { 3294 pt1 = lineutility.ExtendAlongLineDouble(pt0, pt1, stringWidth); 3295 AddModifier2(tg, tg.get_H() + " " + tg.get_Name(), aboveMiddle, -0.7 * csFactor, pt0, pt1, false); 3296 AddModifier2(tg, tg.get_DTG() + WDash, aboveMiddle, 0.7 * csFactor, pt0, pt1, false); 3297 AddModifier2(tg, tg.get_DTG1(), aboveMiddle, 1.7 * csFactor, pt0, pt1, false); 3298 } 3299 if (dist2 > stringWidth + 5 || dist2 > dist || dist3 > stringWidth + 5) { 3300 pt0 = tg.Pixels.get(tg.Pixels.size() - 1); 3301 pt1 = tg.Pixels.get(tg.Pixels.size() - 2); 3302 pt1 = lineutility.ExtendAlongLineDouble(pt0, pt1, stringWidth); 3303 AddModifier2(tg, tg.get_H() + " " + tg.get_Name(), aboveMiddle, -0.7 * csFactor, pt0, pt1, false); 3304 AddModifier2(tg, tg.get_DTG() + WDash, aboveMiddle, 0.7 * csFactor, pt0, pt1, false); 3305 AddModifier2(tg, tg.get_DTG1(), aboveMiddle, 1.7 * csFactor, pt0, pt1, false); 3306 } 3307 } 3308 break; 3309 default: 3310 break; 3311 } 3312 scaleModifiers(tg); 3313 tg.Pixels = origPoints; 3314 } catch (Exception exc) { 3315 ErrorLogger.LogException(_className, "AddModifiersGeo", 3316 new RendererException("Failed inside AddModifiersGeo", exc)); 3317 } 3318 3319 } 3320 3321 /** 3322 * RFA, NFA, FFA need these for line spacing 3323 * 3324 * @param tg 3325 * @return 3326 */ 3327 private static int getRFALines(TGLight tg) { 3328 int lines = 1; 3329 try { 3330 if (tg.get_Name() != null && !tg.get_Name().isEmpty()) { 3331 lines++; 3332 } 3333 if (tg.get_DTG() != null && !tg.get_DTG().isEmpty()) { 3334 lines++; 3335 } else if (tg.get_DTG1() != null && !tg.get_DTG1().isEmpty()) { 3336 lines++; 3337 } 3338 } catch (Exception exc) { 3339 ErrorLogger.LogException(_className, "AddModifiers", 3340 new RendererException("Failed inside AddModifiers", exc)); 3341 } 3342 return lines; 3343 } 3344 3345 /** 3346 * Added sector range fan modifiers based using the calculated orientation 3347 * indicator points 3348 * 3349 * @param tg 3350 * @param converter 3351 * @return 3352 */ 3353 private static void addSectorModifiers(TGLight tg, IPointConversion converter) { 3354 try { 3355 if (tg.get_LineType() == TacticalLines.RANGE_FAN_SECTOR) { 3356 ArrayList<Double> AM = new ArrayList<>(); 3357 ArrayList<Double> AN = new ArrayList<>(); 3358 //get the number of sectors 3359 String X = tg.get_X(); 3360 String[] altitudes = null; 3361 String[] am = tg.get_AM().split(","); 3362 String[] an = tg.get_AN().split(","); 3363 int numSectors = an.length / 2; 3364 //there must be at least one sector 3365 if (numSectors < 1) { 3366 return; 3367 } 3368 if (!X.isEmpty()) { 3369 altitudes = X.split(","); 3370 } 3371 try { 3372 for (String s : am) { 3373 AM.add(Double.parseDouble(s)); 3374 } 3375 for (String s : an) { 3376 AN.add(Double.parseDouble(s)); 3377 } 3378 } catch (NumberFormatException e) { 3379 return; 3380 } 3381 if (numSectors + 1 > AM.size()) { 3382 if (Double.parseDouble(am[0]) != 0d) { 3383 AM.add(0, 0d); 3384 } 3385 } 3386 3387 int n = tg.Pixels.size(); 3388 //pt0 and pt1 are points for the location indicator 3389 POINT2 pt0 = tg.Pixels.get(n - 5); 3390 POINT2 pt1 = tg.Pixels.get(n - 4); 3391 Point2D pt02d = new Point2D.Double(pt0.x, pt0.y); 3392 Point2D pt12d = new Point2D.Double(pt1.x, pt1.y); 3393 pt02d = converter.PixelsToGeo(pt02d); 3394 pt12d = converter.PixelsToGeo(pt12d); 3395 pt0.x = pt02d.getX(); 3396 pt0.y = pt02d.getY(); 3397 pt1.x = pt12d.getX(); 3398 pt1.y = pt12d.getY(); 3399 //azimuth of the orientation indicator 3400 double az12 = mdlGeodesic.GetAzimuth(pt0, pt1); 3401 3402 POINT2 pt2 = null; 3403 ArrayList<POINT2> locModifier = new ArrayList(); 3404 //diagnostic 3405 POINT2 ptLeft = null, ptRight = null; 3406 ArrayList<POINT2> locAZModifier = new ArrayList(); 3407 //end section 3408 Point2D pt22d = null; 3409 double radius = 0; 3410 for (int k = 0; k < numSectors; k++) { 3411 if (AM.size() < k + 2) { 3412 break; 3413 } 3414 radius = (AM.get(k) + AM.get(k + 1)) / 2; 3415 pt2 = mdlGeodesic.geodesic_coordinate(pt0, radius, az12); 3416 //need locModifier in geo pixels 3417 pt22d = new Point2D.Double(pt2.x, pt2.y); 3418 pt22d = converter.GeoToPixels(pt22d); 3419 pt2.x = pt22d.getX(); 3420 pt2.y = pt22d.getY(); 3421 locModifier.add(pt2); 3422 //diagnostic 3423 if (tg.get_HideOptionalLabels()) 3424 continue; 3425 ptLeft = mdlGeodesic.geodesic_coordinate(pt0, radius, AN.get(2 * k)); 3426 //need ptLeft in geo pixels 3427 pt22d = new Point2D.Double(ptLeft.x, ptLeft.y); 3428 pt22d = converter.GeoToPixels(pt22d); 3429 ptLeft.x = pt22d.getX(); 3430 ptLeft.y = pt22d.getY(); 3431 ptRight = mdlGeodesic.geodesic_coordinate(pt0, radius, AN.get(2 * k + 1)); 3432 //need ptRight in geo pixels 3433 pt22d = new Point2D.Double(ptRight.x, ptRight.y); 3434 pt22d = converter.GeoToPixels(pt22d); 3435 ptRight.x = pt22d.getX(); 3436 ptRight.y = pt22d.getY(); 3437 locAZModifier.add(ptLeft); 3438 locAZModifier.add(ptRight); 3439 //end section 3440 } 3441 if (altitudes != null) { 3442 for (int k = 0; k < altitudes.length; k++) { 3443 if (k >= locModifier.size()) { 3444 break; 3445 } 3446 pt0 = locModifier.get(k); 3447 AddAreaModifier(tg, "ALT " + altitudes[k], area, 0, pt0, pt0); 3448 } 3449 } 3450 3451 if (!tg.get_HideOptionalLabels()) { 3452 for (int k = 0; k < numSectors; k++) { 3453 pt0 = locModifier.get(k); 3454 AddAreaModifier(tg, "RG " + removeDecimal(AM.get(k + 1)), area, -1, pt0, pt0); 3455 ptLeft = locAZModifier.get(2 * k); 3456 ptRight = locAZModifier.get(2 * k + 1); 3457 AddAreaModifier(tg, removeDecimal(an[2 * k]), area, 0, ptLeft, ptLeft); 3458 AddAreaModifier(tg, removeDecimal(an[2 * k + 1]), area, 0, ptRight, ptRight); 3459 } 3460 } 3461 } else if (tg.get_LineType() == TacticalLines.RADAR_SEARCH) { 3462 // Copies functionality from RANGE_FAN_SECTOR with one sector and different modifiers 3463 String strLeftRightMinMax = tg.get_LRMM(); 3464 String[] sector = strLeftRightMinMax.split(","); 3465 double left = Double.parseDouble(sector[0]); 3466 double right = Double.parseDouble(sector[1]); 3467 3468 while (left > 360) { 3469 left -= 360; 3470 } 3471 while (right > 360) { 3472 right -= 360; 3473 } 3474 while (left < 0) { 3475 left += 360; 3476 } 3477 while (right < 0) { 3478 right += 360; 3479 } 3480 3481 double orientation = 0; 3482 if (left > right) { 3483 orientation = (left - 360 + right) / 2; 3484 } else { 3485 orientation = (left + right) / 2; 3486 } 3487 3488 double dist = Double.parseDouble(sector[3]); 3489 double radius = dist * 1.1; 3490 3491 POINT2 pt0 = tg.LatLongs.get(0); 3492 Point2D ptPixels = converter.GeoToPixels(new Point2D.Double(pt0.x, pt0.y)); 3493 POINT2 pt0F = new POINT2(); 3494 pt0F.x = ptPixels.getX(); 3495 pt0F.y = ptPixels.getY(); 3496 pt0F.style = pt0.style; 3497 3498 POINT2 pt1 = mdlGeodesic.geodesic_coordinate(pt0, radius, orientation); 3499 ptPixels = converter.GeoToPixels(new Point2D.Double(pt1.x, pt1.y)); 3500 POINT2 pt1F = new POINT2(); 3501 pt1F.x = ptPixels.getX(); 3502 pt1F.y = ptPixels.getY(); 3503 pt1F.style = pt1.style; 3504 3505 dist = lineutility.CalcDistanceDouble(pt0F, pt1F); 3506 double base = 10; 3507 if (dist < 100) { 3508 base = dist / 10; 3509 } 3510 if (base < 5) { 3511 base = 5; 3512 } 3513 double basex2 = 2 * base; 3514 POINT2 ptTipF = lineutility.ExtendAlongLineDouble(pt0F, pt1F, dist + basex2); //was 20 3515 3516 pt0 = pt0F; 3517 pt1 = ptTipF; 3518 3519 ArrayList<Double> AM = new ArrayList<>(); 3520 String[] am = tg.get_AM().split(","); 3521 3522 for (String s : am) { 3523 AM.add(Double.parseDouble(s)); 3524 } 3525 3526 if (AM.size() < 2) { 3527 if (Double.parseDouble(am[0]) != 0d) { 3528 AM.add(0, 0d); 3529 } else { 3530 return; 3531 } 3532 } 3533 3534 Point2D pt02d = new Point2D.Double(pt0.x, pt0.y); 3535 Point2D pt12d = new Point2D.Double(pt1.x, pt1.y); 3536 pt02d = converter.PixelsToGeo(pt02d); 3537 pt12d = converter.PixelsToGeo(pt12d); 3538 pt0.x = pt02d.getX(); 3539 pt0.y = pt02d.getY(); 3540 pt1.x = pt12d.getX(); 3541 pt1.y = pt12d.getY(); 3542 double az12 = mdlGeodesic.GetAzimuth(pt0, pt1); 3543 3544 Point2D pt22d = null; 3545 3546 radius = (AM.get(0) + AM.get(1)) / 2; 3547 POINT2 pt2 = mdlGeodesic.geodesic_coordinate(pt0, radius, az12); 3548 pt22d = new Point2D.Double(pt2.x, pt2.y); 3549 pt22d = converter.GeoToPixels(pt22d); 3550 pt2.x = pt22d.getX(); 3551 pt2.y = pt22d.getY(); 3552 AddAreaModifier(tg, tg.get_Name(), area, -1, pt2, pt2); 3553 } 3554 } catch (Exception exc) { 3555 ErrorLogger.LogException(_className, "addSectorModifiers", 3556 new RendererException("Failed inside addSectorModifiers", exc)); 3557 } 3558 } 3559 3560 /** 3561 * Called by the renderer after tg.Pixels has been filled with the 3562 * calculated points. The modifier path depends on points calculated by 3563 * CELineArray. 3564 * 3565 * @param tg 3566 */ 3567 public static void AddModifiers2(TGLight tg, IPointConversion converter) { 3568 try { 3569 if (tg.Pixels == null || tg.Pixels.isEmpty()) { 3570 return; 3571 } 3572 switch (tg.get_LineType()) { 3573 case TacticalLines.BS_RECTANGLE: 3574 case TacticalLines.BBS_RECTANGLE: 3575 case TacticalLines.CONVOY: 3576 case TacticalLines.HCONVOY: 3577 case TacticalLines.BREACH: 3578 case TacticalLines.BYPASS: 3579 case TacticalLines.CANALIZE: 3580 case TacticalLines.PENETRATE: 3581 case TacticalLines.CLEAR: 3582 case TacticalLines.DISRUPT: 3583 case TacticalLines.FIX: 3584 case TacticalLines.ISOLATE: 3585 case TacticalLines.OCCUPY: 3586 case TacticalLines.RETAIN: 3587 case TacticalLines.SECURE: 3588 case TacticalLines.CONTROL: 3589 case TacticalLines.LOCATE: 3590 case TacticalLines.AREA_DEFENSE: 3591 case TacticalLines.CONTAIN: 3592 case TacticalLines.SEIZE: 3593 case TacticalLines.CAPTURE: 3594 case TacticalLines.EVACUATE: 3595 case TacticalLines.TURN: 3596 case TacticalLines.CORDONKNOCK: 3597 case TacticalLines.CORDONSEARCH: 3598 case TacticalLines.DENY: 3599 case TacticalLines.ESCORT: 3600 case TacticalLines.EXFILTRATION: 3601 case TacticalLines.INFILTRATION: 3602 case TacticalLines.FOLLA: 3603 case TacticalLines.FOLSP: 3604 case TacticalLines.ACA_RECTANGULAR: 3605 case TacticalLines.ACA_CIRCULAR: 3606 case TacticalLines.RECTANGULAR: 3607 case TacticalLines.CUED_ACQUISITION: 3608 case TacticalLines.CIRCULAR: 3609 case TacticalLines.BDZ: 3610 case TacticalLines.BBS_POINT: 3611 case TacticalLines.FSA_CIRCULAR: 3612 case TacticalLines.NOTACK: 3613 case TacticalLines.ATI_CIRCULAR: 3614 case TacticalLines.CFFZ_CIRCULAR: 3615 case TacticalLines.SENSOR_CIRCULAR: 3616 case TacticalLines.CENSOR_CIRCULAR: 3617 case TacticalLines.DA_CIRCULAR: 3618 case TacticalLines.CFZ_CIRCULAR: 3619 case TacticalLines.ZOR_CIRCULAR: 3620 case TacticalLines.TBA_CIRCULAR: 3621 case TacticalLines.TVAR_CIRCULAR: 3622 case TacticalLines.FFA_CIRCULAR: 3623 case TacticalLines.NFA_CIRCULAR: 3624 case TacticalLines.RFA_CIRCULAR: 3625 case TacticalLines.KILLBOXBLUE_CIRCULAR: 3626 case TacticalLines.KILLBOXPURPLE_CIRCULAR: 3627 case TacticalLines.BLOCK: 3628 case TacticalLines.FFA_RECTANGULAR: 3629 case TacticalLines.NFA_RECTANGULAR: 3630 case TacticalLines.RFA_RECTANGULAR: 3631 case TacticalLines.KILLBOXBLUE_RECTANGULAR: 3632 case TacticalLines.KILLBOXPURPLE_RECTANGULAR: 3633 case TacticalLines.FSA_RECTANGULAR: 3634 case TacticalLines.SHIP_AOI_RECTANGULAR: 3635 case TacticalLines.DEFENDED_AREA_RECTANGULAR: 3636 case TacticalLines.ATI_RECTANGULAR: 3637 case TacticalLines.CFFZ_RECTANGULAR: 3638 case TacticalLines.SENSOR_RECTANGULAR: 3639 case TacticalLines.CENSOR_RECTANGULAR: 3640 case TacticalLines.DA_RECTANGULAR: 3641 case TacticalLines.CFZ_RECTANGULAR: 3642 case TacticalLines.ZOR_RECTANGULAR: 3643 case TacticalLines.TBA_RECTANGULAR: 3644 case TacticalLines.TVAR_RECTANGULAR: 3645 case TacticalLines.PAA: 3646 case TacticalLines.PAA_RECTANGULAR: 3647 case TacticalLines.RECTANGULAR_TARGET: 3648 case TacticalLines.PAA_CIRCULAR: 3649 case TacticalLines.RANGE_FAN: 3650 case TacticalLines.RANGE_FAN_SECTOR: 3651 case TacticalLines.RADAR_SEARCH: 3652 case TacticalLines.SHIP_AOI_CIRCULAR: 3653 case TacticalLines.MFLANE: 3654 case TacticalLines.ENVELOPMENT: 3655 case TacticalLines.MOBILE_DEFENSE: 3656 break; 3657 default: 3658 return; 3659 } 3660 //end section 3661 ArrayList<POINT2> origPoints = lineutility.getDeepCopy(tg.Pixels); 3662 int n = tg.Pixels.size(); 3663 if (tg.modifiers == null) { 3664 tg.modifiers = new ArrayList(); 3665 } 3666 Font font = tg.get_Font(); 3667 POINT2 ptCenter = null; 3668 double csFactor = 1d;//this will be used for text spacing the 3d map (CommandCight) 3669 //String affiliation=tg.get_Affiliation(); 3670 int linetype = tg.get_LineType(); 3671 POINT2 pt0 = null, pt1 = null, pt2 = null, pt3 = null; 3672 int j = 0, k = 0; 3673 double dist = 0; 3674 String label = GetCenterLabel(tg); 3675 String[] X = null; 3676 int lastIndex = tg.Pixels.size() - 1; 3677 int nextToLastIndex = 0; 3678 if (tg.Pixels.size() > 1) { 3679 nextToLastIndex = tg.Pixels.size() - 2; 3680 } 3681 POINT2 ptLast = new POINT2(tg.Pixels.get(lastIndex)); 3682 POINT2 ptNextToLast = null; 3683 if (tg.Pixels.size() > 1) { 3684 ptNextToLast = new POINT2(tg.Pixels.get(nextToLastIndex)); 3685 } 3686 String WDash = ""; // Dash between W and W1 if they're not empty 3687 String TSpace = "", TDash = ""; // Space or dash between label and T modifier if T isn't empty 3688 if (tg.get_DTG() != null && tg.get_DTG1() != null && !tg.get_DTG().isEmpty() && !tg.get_DTG1().isEmpty()) { 3689 WDash = " - "; 3690 } 3691 if (tg.get_Name() != null && !tg.get_Name().isEmpty()) { 3692 TSpace = " "; 3693 TDash = " - "; 3694 } 3695 3696 POINT2 ptLeft = null, ptRight = null; 3697 BufferedImage bi = new BufferedImage(8, 8, BufferedImage.TYPE_INT_ARGB); 3698 Graphics2D g2d = bi.createGraphics(); 3699 g2d.setFont(tg.get_Font()); 3700 FontMetrics metrics = g2d.getFontMetrics(); 3701 int stringWidth = 0, rfaLines = 0; 3702 pt0 = new POINT2(tg.Pixels.get(0)); 3703 if (tg.Pixels.size() > 1) { 3704 pt1 = new POINT2(tg.Pixels.get(1)); 3705 } 3706 3707 POINT2[] pts = null; 3708 // if the client is the 3d map (CS) then we want to shrink the spacing bnetween 3709 // the lines of text 3710 if (tg.get_Client().equals("cpof3d")) { 3711 csFactor = 0.9d; 3712 } 3713 3714 shiftModifierPath(tg, pt0, pt1, ptLast, ptNextToLast); 3715 switch (linetype) { 3716 case TacticalLines.BS_RECTANGLE: 3717 case TacticalLines.BBS_RECTANGLE: 3718 pts = new POINT2[4]; 3719 for (j = 0; j < 4; j++) { 3720 pts[j] = tg.Pixels.get(j); 3721 } 3722 ptCenter = lineutility.CalcCenterPointDouble2(pts, 4); 3723 AddIntegralAreaModifier(tg, tg.get_Name(), area, -0.125 * csFactor, ptCenter, ptCenter, false); 3724 break; 3725 case TacticalLines.CONVOY: 3726 case TacticalLines.HCONVOY: 3727 pt2 = lineutility.MidPointDouble(tg.Pixels.get(0), tg.Pixels.get(3), 0); 3728 pt3 = lineutility.MidPointDouble(tg.Pixels.get(1), tg.Pixels.get(2), 0); 3729 AddIntegralAreaModifier(tg, tg.get_V(), aboveEndInside, 0, pt2, pt3, false); 3730 AddIntegralAreaModifier(tg, tg.get_H(), aboveStartInside, 0, pt2, pt3, false); 3731 addDTG(tg, aboveMiddle, 1.2 * csFactor, 2.2 * csFactor, pt2, pt3, metrics); 3732 break; 3733 case TacticalLines.BREACH: 3734 case TacticalLines.BYPASS: 3735 case TacticalLines.CANALIZE: 3736 pt0 = tg.Pixels.get(1); 3737 pt1 = tg.Pixels.get(2); 3738 //pt1=lineutility.ExtendAlongLineDouble(pt1, pt0, -10); 3739 AddIntegralAreaModifier(tg, label, aboveMiddlePerpendicular, -0.125 * csFactor, pt0, pt1, true); 3740 break; 3741 case TacticalLines.PENETRATE: 3742 case TacticalLines.CLEAR: 3743 pt0 = tg.Pixels.get(2); 3744 pt1 = tg.Pixels.get(3); 3745 //pt1=lineutility.ExtendAlongLineDouble(pt1, pt0, -10); 3746 AddIntegralAreaModifier(tg, label, aboveMiddle, -0.125 * csFactor, pt0, pt1, true); 3747 break; 3748 case TacticalLines.DISRUPT: 3749 pt0 = tg.Pixels.get(4); 3750 pt1 = tg.Pixels.get(5); 3751 //pt1=lineutility.ExtendAlongLineDouble(pt1, pt0, -10); 3752 AddIntegralAreaModifier(tg, label, aboveMiddle, -0.125 * csFactor, pt0, pt1, true); 3753 break; 3754 case TacticalLines.FIX: 3755 pt0 = tg.Pixels.get(0); 3756 pt1 = tg.Pixels.get(1); 3757 //pt1=lineutility.ExtendAlongLineDouble(pt1, pt0, -10); 3758 AddIntegralAreaModifier(tg, label, aboveMiddle, -0.125 * csFactor, pt0, pt1, true); 3759 break; 3760 case TacticalLines.ISOLATE: 3761 case TacticalLines.OCCUPY: 3762 case TacticalLines.RETAIN: 3763 case TacticalLines.SECURE: 3764 case TacticalLines.CONTROL: 3765 case TacticalLines.LOCATE: 3766 case TacticalLines.AREA_DEFENSE: 3767 pt0 = tg.Pixels.get(13); 3768 pt1 = tg.Pixels.get(14); 3769 //pt1=lineutility.ExtendAlongLineDouble(pt1, pt0, -10); 3770 ptCenter = lineutility.MidPointDouble(pt0, pt1, 0); 3771 AddIntegralAreaModifier(tg, label, aboveMiddle, -0.125 * csFactor, ptCenter, ptCenter, true); 3772 break; 3773 case TacticalLines.CONTAIN: 3774 pt0 = tg.Pixels.get(13); 3775 pt1 = tg.Pixels.get(14); 3776 //pt1=lineutility.ExtendAlongLineDouble(pt1, pt0, -10); 3777 AddIntegralAreaModifier(tg, label, aboveMiddle, -0.125 * csFactor, pt0, pt1, true); 3778 3779 // Contain always has "ENY" even if friendly (not N modifier) 3780 for (j = 0; j < n; j++) { 3781 if (tg.Pixels.get(j).style == 14) { 3782 pt0 = tg.Pixels.get(j); 3783 pt1 = tg.Pixels.get(j + 1); 3784 AddIntegralAreaModifier(tg, "ENY", aboveMiddle, 0, pt0, pt1, true); 3785 break; 3786 } 3787 } 3788 break; 3789 case TacticalLines.TURN: 3790 pt0 = tg.Pixels.get(12); 3791 pt1 = tg.Pixels.get(13); 3792 ptCenter = lineutility.MidPointDouble(pt0, pt1, 0); 3793 AddIntegralAreaModifier(tg, label, area, -0.125 * csFactor, ptCenter, ptCenter, true); 3794 break; 3795 case TacticalLines.SEIZE: 3796 case TacticalLines.CAPTURE: 3797 case TacticalLines.EVACUATE: 3798 pt0 = tg.Pixels.get(26); 3799 pt1 = tg.Pixels.get(27); 3800 //pt1=lineutility.ExtendAlongLineDouble(pt1, pt0, -10); 3801 ptCenter = lineutility.MidPointDouble(pt0, pt1, 0); 3802 AddIntegralAreaModifier(tg, label, aboveMiddle, -0.125 * csFactor, ptCenter, ptCenter, true); 3803 break; 3804 case TacticalLines.DEFENDED_AREA_RECTANGULAR: 3805 ptLeft = lineutility.MidPointDouble(tg.Pixels.get(0), tg.Pixels.get(1), 0); 3806 ptRight = lineutility.MidPointDouble(tg.Pixels.get(2), tg.Pixels.get(3), 0); 3807 AddIntegralAreaModifier(tg, label + TDash + tg.get_Name(), aboveMiddle, 0, ptLeft, ptRight, false); 3808 break; 3809 case TacticalLines.SHIP_AOI_RECTANGULAR: 3810 if (tg.Pixels.get(0).x > tg.Pixels.get(3).x) { 3811 AddIntegralAreaModifier(tg, label, aboveMiddle, csFactor, tg.Pixels.get(0), tg.Pixels.get(3), false); 3812 } else { 3813 AddIntegralAreaModifier(tg, label, aboveMiddle, csFactor, tg.Pixels.get(1), tg.Pixels.get(2), false); 3814 } 3815 break; 3816 case TacticalLines.NOTACK: 3817 ptCenter = lineutility.MidPointDouble(tg.Pixels.get(0), tg.Pixels.get(tg.Pixels.size() / 2), 0); 3818 AddIntegralAreaModifier(tg, label, area, -1, ptCenter, ptCenter, false); 3819 addDTG(tg, area, csFactor, 2 * csFactor, ptCenter, ptCenter, metrics); 3820 break; 3821 case TacticalLines.SHIP_AOI_CIRCULAR: 3822 // Moved from AddModifiersGeo() 3823 // AddModifiersGeo() called before getGeoEllipse(). Unable to use getMBR with single anchor point 3824 3825 // Get variables from AddModifiersGeo 3826 POINT2 lr = new POINT2(tg.Pixels.get(0)); 3827 POINT2 ll = new POINT2(tg.Pixels.get(0)); 3828 POINT2 ul = new POINT2(tg.Pixels.get(0)); 3829 POINT2 ur = new POINT2(tg.Pixels.get(0)); 3830 GetMBR(tg, ul, ur, lr, ll); 3831 3832 AddIntegralAreaModifier(tg, label, aboveMiddle, csFactor, ll, lr, false); 3833 break; 3834 case TacticalLines.MFLANE: 3835 //pt0=tg.Pixels.get(7); 3836 //pt1=tg.Pixels.get(5); 3837 pt0 = tg.Pixels.get(4); 3838 pt1 = tg.Pixels.get(2); 3839 if (tg.Pixels.get(0).y < tg.Pixels.get(1).y) { 3840 addDTG(tg, aboveMiddle, 0.5 * csFactor, 1.5 * csFactor, pt0, pt1, metrics); 3841 } else { 3842 addDTG(tg, aboveMiddle, -0.5 * csFactor, -1.5 * csFactor, pt0, pt1, metrics); 3843 } 3844 break; 3845 case TacticalLines.CORDONKNOCK: 3846 case TacticalLines.CORDONSEARCH: 3847 case TacticalLines.DENY: 3848 pt0 = tg.Pixels.get(13); 3849 pt1 = tg.Pixels.get(0); 3850 stringWidth = metrics.stringWidth(label); 3851 if (pt0.x < pt1.x) { 3852 stringWidth = -stringWidth; 3853 } 3854 pt1 = lineutility.ExtendAlongLineDouble2(pt0, pt1, 0.75 * stringWidth); 3855 ptCenter = lineutility.MidPointDouble(pt0, pt1, 0); 3856 AddIntegralAreaModifier(tg, label, aboveMiddle, 0, ptCenter, ptCenter, true); 3857 break; 3858 case TacticalLines.ESCORT: 3859 if(tg.Pixels.size() == 6) { 3860 if (tg.Pixels.get(2).x == tg.Pixels.get(3).x && 3861 tg.Pixels.get(2).y == tg.Pixels.get(3).y) { 3862 //No Room for E labels 3863 break;//? 3864 } 3865 AddIntegralAreaModifier(tg, label, toEnd, 0, tg.Pixels.get(2), tg.Pixels.get(1), true); 3866 AddIntegralAreaModifier(tg, label, toEnd, 0, tg.Pixels.get(3), tg.Pixels.get(4), true); 3867 } 3868 break; 3869 case TacticalLines.EXFILTRATION: 3870 case TacticalLines.INFILTRATION: 3871 AddIntegralAreaModifier(tg, label, aboveMiddle, 0, pt0, pt1 , true); 3872 break; 3873 case TacticalLines.FOLLA: 3874 pt0 = tg.Pixels.get(0); 3875 pt1 = lineutility.MidPointDouble(tg.Pixels.get(5), tg.Pixels.get(6), 0); 3876 pt1 = lineutility.ExtendAlongLineDouble(pt1, pt0, -10); 3877 AddIntegralAreaModifier(tg, tg.get_Name(), aboveMiddle, 0, pt0, pt1, true); 3878 break; 3879 case TacticalLines.FOLSP: 3880 pt0 = tg.Pixels.get(3); 3881 pt1 = tg.Pixels.get(6); 3882 pt1 = lineutility.ExtendAlongLineDouble(pt1, pt0, -10); 3883 AddIntegralAreaModifier(tg, tg.get_Name(), aboveMiddle, 0, pt0, pt1, true); 3884 break; 3885 case TacticalLines.ACA_RECTANGULAR: 3886 ptLeft = lineutility.MidPointDouble(tg.Pixels.get(0), tg.Pixels.get(1), 0); 3887 ptRight = lineutility.MidPointDouble(tg.Pixels.get(2), tg.Pixels.get(3), 0); 3888 AddModifier2(tg, label + TSpace + tg.get_Name(), aboveMiddle, -3 * csFactor, ptLeft, ptRight, false); 3889 AddModifier2(tg, tg.get_T1(), aboveMiddle, -2 * csFactor, ptLeft, ptRight, false, "T1"); 3890 AddModifier2(tg, "MIN ALT: " + tg.get_X(), aboveMiddle, -1 * csFactor, ptLeft, ptRight, false, "H"); 3891 AddModifier2(tg, "MAX ALT: " + tg.get_X1(), aboveMiddle, 0, ptLeft, ptRight, false, "H1"); 3892 AddModifier2(tg, "GRID " + tg.get_Location(), aboveMiddle, 1 * csFactor, ptLeft, ptRight, false, "H2"); 3893 AddModifier2(tg, "EFF " + tg.get_DTG() + WDash, aboveMiddle, 2 * csFactor, ptLeft, ptRight, false, "W"); 3894 AddModifier2(tg, tg.get_DTG1(), aboveMiddle, 3 * csFactor, ptLeft, ptRight, false, "W1"); 3895 break; 3896 case TacticalLines.ACA_CIRCULAR: 3897 ptCenter = lineutility.CalcCenterPointDouble2(tg.Pixels.toArray(), tg.Pixels.size()); 3898 AddIntegralAreaModifier(tg, label + TSpace + tg.get_Name(), area, -3 * csFactor, ptCenter, ptCenter, false); 3899 AddModifier2(tg, tg.get_T1(), area, -2 * csFactor, ptCenter, ptCenter, false, "T1"); 3900 AddIntegralAreaModifier(tg, "MIN ALT: " + tg.get_X(), area, -1 * csFactor, ptCenter, ptCenter, false, "H"); 3901 AddIntegralAreaModifier(tg, "MAX ALT: " + tg.get_X1(), area, 0, ptCenter, ptCenter, false, "H1"); 3902 AddIntegralAreaModifier(tg, "GRID " + tg.get_Location(), area, 1 * csFactor, ptCenter, ptCenter, false, "H2"); 3903 AddIntegralAreaModifier(tg, "EFF " + tg.get_DTG() + WDash, area, 2 * csFactor, ptCenter, ptCenter, false, "W"); 3904 AddIntegralAreaModifier(tg, tg.get_DTG1(), area, 3 * csFactor, ptCenter, ptCenter, false, "W1"); 3905 break; 3906 case TacticalLines.FSA_CIRCULAR: 3907 case TacticalLines.ATI_CIRCULAR: 3908 case TacticalLines.CFFZ_CIRCULAR: 3909 case TacticalLines.SENSOR_CIRCULAR: 3910 case TacticalLines.CENSOR_CIRCULAR: 3911 case TacticalLines.DA_CIRCULAR: 3912 case TacticalLines.CFZ_CIRCULAR: 3913 case TacticalLines.ZOR_CIRCULAR: 3914 case TacticalLines.TBA_CIRCULAR: 3915 case TacticalLines.TVAR_CIRCULAR: 3916 case TacticalLines.KILLBOXBLUE_CIRCULAR: 3917 case TacticalLines.KILLBOXPURPLE_CIRCULAR: 3918 ptCenter = lineutility.MidPointDouble(tg.Pixels.get(0), tg.Pixels.get(tg.Pixels.size() / 2), 0); 3919 AddIntegralAreaModifier(tg, label, area, -0.5 * csFactor, ptCenter, ptCenter, false); 3920 AddIntegralAreaModifier(tg, tg.get_Name(), area, 0.5 * csFactor, ptCenter, ptCenter, false); 3921 AddOffsetModifier(tg, tg.get_DTG() + WDash, toEnd, -1 * csFactor, tg.Pixels.size() / 2, 0, 4, "left"); 3922 AddOffsetModifier(tg, tg.get_DTG1(), toEnd, 0, tg.Pixels.size() / 2, 0, 4, "left"); 3923 break; 3924 case TacticalLines.FFA_CIRCULAR: 3925 case TacticalLines.NFA_CIRCULAR: 3926 case TacticalLines.RFA_CIRCULAR: 3927 rfaLines = getRFALines(tg); 3928 ptCenter = lineutility.MidPointDouble(tg.Pixels.get(0), tg.Pixels.get(51), 0); 3929 switch (rfaLines) { 3930 case 3: //2 valid modifiers and a label 3931 AddIntegralAreaModifier(tg, label, area, -1 * csFactor, ptCenter, ptCenter, true); 3932 AddIntegralAreaModifier(tg, tg.get_Name(), area, 0, ptCenter, ptCenter, true); 3933 addDTG(tg, area, 1 * csFactor, 2 * csFactor, ptCenter, ptCenter, metrics); 3934 break; 3935 case 2: //one valid modifier and a label 3936 AddIntegralAreaModifier(tg, label, area, -0.5 * csFactor, ptCenter, ptCenter, true); 3937 if (tg.get_Name() != null && !tg.get_Name().isEmpty()) { 3938 AddIntegralAreaModifier(tg, tg.get_Name(), area, 0.5 * csFactor, ptCenter, ptCenter, true); 3939 } else { 3940 addDTG(tg, area, 0.5 * csFactor, 1.5 * csFactor, ptCenter, ptCenter, metrics); 3941 } 3942 break; 3943 default: //one label only 3944 AddIntegralAreaModifier(tg, label, area, 0, ptCenter, ptCenter, true); 3945 break; 3946 } 3947 break; 3948 case TacticalLines.BLOCK: 3949 //for (j = 0; j < tg.Pixels.size(); j++) 3950 for (j = 0; j < n; j++) { 3951 if (tg.Pixels.get(j).style == 14) { 3952 AddIntegralModifier(tg, label, aboveMiddle, 0, j, j + 1); 3953 break; 3954 } 3955 } 3956 break; 3957 case TacticalLines.FFA_RECTANGULAR: 3958 case TacticalLines.NFA_RECTANGULAR: 3959 case TacticalLines.RFA_RECTANGULAR: 3960 rfaLines = getRFALines(tg); 3961 pt0 = lineutility.MidPointDouble(tg.Pixels.get(0), tg.Pixels.get(1), 0); 3962 pt1 = lineutility.MidPointDouble(tg.Pixels.get(2), tg.Pixels.get(3), 0); 3963 switch (rfaLines) { 3964 case 3: //two valid modifiers and one label 3965 AddModifier2(tg, label, aboveMiddle, -1 * csFactor, pt0, pt1, false); 3966 AddModifier2(tg, tg.get_Name(), aboveMiddle, 0, pt0, pt1, false); 3967 addDTG(tg, aboveMiddle, 1 * csFactor, 2 * csFactor, pt0, pt1, metrics); 3968 break; 3969 case 2: //one valid modifier and one label 3970 AddModifier2(tg, label, aboveMiddle, -0.5 * csFactor, pt0, pt1, false); 3971 if (tg.get_Name() != null && !tg.get_Name().isEmpty()) { 3972 AddModifier2(tg, tg.get_Name(), aboveMiddle, 0.5 * csFactor, pt0, pt1, false); 3973 } else { 3974 addDTG(tg, aboveMiddle, 0.5 * csFactor, 1.5 * csFactor, pt0, pt1, metrics); 3975 } 3976 break; 3977 default: //one label only 3978 AddModifier2(tg, label, aboveMiddle, 0, pt0, pt1, false); 3979 break; 3980 } 3981 break; 3982 case TacticalLines.KILLBOXBLUE_RECTANGULAR: 3983 case TacticalLines.KILLBOXPURPLE_RECTANGULAR: 3984 case TacticalLines.FSA_RECTANGULAR: 3985 case TacticalLines.ATI_RECTANGULAR: 3986 case TacticalLines.CFFZ_RECTANGULAR: 3987 case TacticalLines.SENSOR_RECTANGULAR: 3988 case TacticalLines.CENSOR_RECTANGULAR: 3989 case TacticalLines.DA_RECTANGULAR: 3990 case TacticalLines.CFZ_RECTANGULAR: 3991 case TacticalLines.ZOR_RECTANGULAR: 3992 case TacticalLines.TBA_RECTANGULAR: 3993 case TacticalLines.TVAR_RECTANGULAR: 3994 ptLeft = lineutility.MidPointDouble(tg.Pixels.get(0), tg.Pixels.get(1), 0); 3995 ptRight = lineutility.MidPointDouble(tg.Pixels.get(2), tg.Pixels.get(3), 0); 3996 AddModifier2(tg, label, aboveMiddle, -0.5 * csFactor, ptLeft, ptRight, false); 3997 AddModifier2(tg, tg.get_Name(), aboveMiddle, 0.5 * csFactor, ptLeft, ptRight, false); 3998 pt0 = tg.Pixels.get(0); 3999 pt1 = tg.Pixels.get(1); 4000 pt2 = tg.Pixels.get(2); 4001 pt3 = tg.Pixels.get(3); 4002 if (tg.get_Client().equalsIgnoreCase("ge")) { 4003 pt0.x -= font.getSize() / 2; 4004 pt2.x -= font.getSize() / 2; 4005 } 4006 if (!tg.get_Client().equalsIgnoreCase("ge"))//added 2-27-12 4007 { 4008 clsUtility.shiftModifiersLeft(pt0, pt3, 12.5); 4009 clsUtility.shiftModifiersLeft(pt1, pt2, 12.5); 4010 } 4011 if (ptLeft.x == ptRight.x) { 4012 ptRight.x += 1; 4013 } 4014 if (ptLeft.x < ptRight.x) { 4015 AddModifier(tg, tg.get_DTG() + WDash, toEnd, 0, pt0, pt3);//was 1,2 switched for CPOF 4016 AddModifier(tg, tg.get_DTG1(), toEnd, 1 * csFactor, pt0, pt3);//was 1,2 4017 } else { 4018 AddModifier(tg, tg.get_DTG() + WDash, toEnd, 0, pt2, pt1);//was 3,0 //switched for CPOF 4019 AddModifier(tg, tg.get_DTG1(), toEnd, 1 * csFactor, pt2, pt1);//was 3,0 4020 } 4021 4022 break; 4023 case TacticalLines.PAA_RECTANGULAR: 4024 AddIntegralModifier(tg, label, aboveMiddlePerpendicular, 0, 0, 1, true); 4025 AddIntegralModifier(tg, label, aboveMiddle, 0, 1, 2, true); 4026 AddIntegralModifier(tg, label, aboveMiddlePerpendicular, 0, 2, 3, true); 4027 AddIntegralModifier(tg, label, aboveMiddle, 0, 3, 0, true); 4028 rfaLines = getRFALines(tg); 4029 pt0 = lineutility.MidPointDouble(tg.Pixels.get(0), tg.Pixels.get(1), 0); 4030 pt1 = lineutility.MidPointDouble(tg.Pixels.get(2), tg.Pixels.get(3), 0); 4031 switch (rfaLines) { 4032 case 3: // two valid modifiers 4033 AddModifier2(tg, tg.get_Name(), aboveMiddle, -0.5, pt0, pt1, false); 4034 addDTG(tg, aboveMiddle, 0.5 * csFactor, 1.5 * csFactor, pt0, pt1, metrics); 4035 break; 4036 case 2: // one valid modifier 4037 if (tg.get_Name() != null && !tg.get_Name().isEmpty()) { 4038 AddModifier2(tg, tg.get_Name(), aboveMiddle, 0, pt0, pt1, false); 4039 } else { 4040 addDTG(tg, aboveMiddle, 0, csFactor, pt0, pt1, metrics); 4041 } 4042 break; 4043 default: 4044 break; 4045 } 4046 break; 4047 case TacticalLines.PAA_CIRCULAR: 4048 for (int i = 0; i < 4; i++) { 4049 AddIntegralModifier(tg, label, area, -0.5 * csFactor, n / 4 * i, n / 4 * i, false); 4050 } 4051 4052 rfaLines = getRFALines(tg); 4053 ptCenter = lineutility.MidPointDouble(tg.Pixels.get(0), tg.Pixels.get((int) (n / 2.0 + 0.5)), 0); 4054 switch (rfaLines) { 4055 case 3: // two valid modifiers 4056 AddIntegralAreaModifier(tg, tg.get_Name(), area, -0.5, ptCenter, ptCenter, false); 4057 addDTG(tg, area, 0.5 * csFactor, 1.5 * csFactor, ptCenter, ptCenter, metrics); 4058 break; 4059 case 2: // one valid modifier 4060 if (tg.get_Name() != null && !tg.get_Name().isEmpty()) { 4061 AddIntegralAreaModifier(tg, tg.get_Name(), area, 0, ptCenter, ptCenter, false); 4062 } else { 4063 addDTG(tg, area, 0, csFactor, ptCenter, ptCenter, metrics); 4064 } 4065 break; 4066 default: 4067 break; 4068 } 4069 break; 4070 case TacticalLines.RANGE_FAN: 4071 if (tg.get_X() != null) { 4072 X = tg.get_X().split(","); 4073 for (j = 0; j < X.length; j++) { 4074 if (tg.Pixels.size() > j * 102 + 25) { 4075 pt0 = tg.Pixels.get(j * 102 + 25); 4076 AddAreaModifier(tg, "ALT " + X[j], area, 0, pt0, pt0); 4077 } 4078 } 4079 } 4080 if(!tg.get_HideOptionalLabels()) 4081 { 4082 String[] am = tg.get_AM().split(","); 4083 for(j=0;j<am.length;j++) 4084 { 4085 if (tg.Pixels.size() > j * 102 + 25) { 4086 pt0 = tg.Pixels.get(j * 102 + 25); 4087 //AddAreaModifier(tg, "RG " + am[j], area, -1, pt0, pt0); 4088 if(j==0) 4089 AddAreaModifier(tg, "MIN RG " + removeDecimal(am[j]), 3, -1, pt0, pt0); 4090 else 4091 AddAreaModifier(tg, "MAX RG " + "(" + Integer.toString(j) + ") " + removeDecimal(am[j]), 3, -1, pt0, pt0); 4092 } 4093 } 4094 }// end if set range fan text 4095 break; 4096 case TacticalLines.RANGE_FAN_SECTOR: 4097 case TacticalLines.RADAR_SEARCH: 4098 addSectorModifiers(tg, converter); 4099 break; 4100 case TacticalLines.ENVELOPMENT: 4101 AddIntegralModifier(tg, label, aboveMiddle, 0, 0, 1, true); 4102 break; 4103 case TacticalLines.MOBILE_DEFENSE: 4104 AddIntegralModifier(tg, label, area, 0, 16, 16, true); 4105 break; 4106 default: 4107 break; 4108 }//end switch 4109 scaleModifiers(tg); 4110 tg.Pixels = origPoints; 4111 g2d.dispose(); 4112 g2d = null; 4113 } catch (Exception exc) { 4114 ErrorLogger.LogException(_className, "AddModifiers2", 4115 new RendererException("Failed inside AddModifiers2", exc)); 4116 } 4117 } 4118 4119 /** 4120 * Displays the tg modifiers using a client Graphics2D, this is an option 4121 * provided to clients for displaying modifiers without using shapes 4122 * 4123 * @param tg the tactical graphic 4124 * @param g2d the graphics object for drawing 4125 * @deprecated 4126 */ 4127 public static void DisplayModifiers(TGLight tg, 4128 Graphics2D g2d) { 4129 try { 4130 Font font = g2d.getFont(); 4131 int j = 0; 4132 Modifier2 modifier = null; 4133 g2d.setBackground(Color.white); 4134 POINT2 pt = null; 4135 double theta = 0; 4136 int stringWidth = 0, stringHeight = 0; 4137 FontMetrics metrics = g2d.getFontMetrics(); 4138 String s = ""; 4139 int x = 0, y = 0; 4140 POINT2 pt1 = null, pt2 = null; 4141 int quadrant = -1; 4142 int n = tg.Pixels.size(); 4143 //for (j = 0; j < tg.modifiers.size(); j++) 4144 for (j = 0; j < n; j++) { 4145 modifier = (Modifier2) tg.modifiers.get(j); 4146 double lineFactor = modifier.lineFactor; 4147 s = modifier.text; 4148 double x1 = 0, y1 = 0, x2 = 0, y2 = 0; 4149 pt = modifier.textPath[0]; 4150 x1 = pt.x; 4151 y1 = pt.y; 4152 pt = modifier.textPath[1]; 4153 x2 = pt.x; 4154 y2 = pt.y; 4155 theta = Math.atan2(y2 - y1, x2 - x1); 4156 POINT2 midPt; 4157 if (x1 > x2) { 4158 theta -= Math.PI; 4159 } 4160 switch (modifier.type) { 4161 case toEnd: //corresponds to LabelAndTextBeforeLineTG 4162 g2d.rotate(theta, x1, y1); 4163 stringWidth = metrics.stringWidth(s); 4164 stringHeight = font.getSize(); 4165 if (x1 < x2 || (x1 == x2 && y1 > y2)) { 4166 x = (int) x1 - stringWidth; 4167 y = (int) y1 - (int) stringHeight / 2 + (int) (lineFactor * stringHeight); 4168 g2d.setColor(tg.get_FontBackColor()); 4169 g2d.clearRect(x, y, stringWidth, stringHeight); 4170 y = (int) y1 + (int) stringHeight / 2 + (int) (lineFactor * stringHeight); 4171 g2d.setColor(tg.get_TextColor()); 4172 g2d.drawString(s, x, y); 4173 } else { 4174 x = (int) x1; 4175 y = (int) y1 - (int) stringHeight / 2 + (int) (lineFactor * stringHeight); 4176 g2d.setColor(tg.get_FontBackColor()); 4177 g2d.clearRect(x, y, stringWidth, stringHeight); 4178 y = (int) y1 + (int) stringHeight / 2 + (int) (lineFactor * stringHeight); 4179 g2d.setColor(tg.get_TextColor()); 4180 g2d.drawString(s, x, y); 4181 } 4182 break; 4183 case aboveMiddle: 4184 midPt = new POINT2((x1 + x2) / 2, (y1 + y2) / 2); 4185 g2d.rotate(theta, midPt.x, midPt.y); 4186 stringWidth = metrics.stringWidth(s); 4187 stringHeight = font.getSize(); 4188 x = (int) midPt.x - stringWidth / 2; 4189 y = (int) midPt.y - (int) stringHeight / 2 + (int) (lineFactor * stringHeight); 4190 g2d.setColor(tg.get_FontBackColor()); 4191 g2d.clearRect(x, y, stringWidth, stringHeight); 4192 y = (int) midPt.y + (int) (stringHeight / 2) + (int) (lineFactor * stringHeight); 4193 g2d.setColor(tg.get_TextColor()); 4194 g2d.drawString(s, x, y); 4195 break; 4196 case area: 4197 g2d.rotate(0, x1, y1); 4198 stringWidth = metrics.stringWidth(s); 4199 stringHeight = font.getSize(); 4200 4201 x = (int) x1 - stringWidth / 2; 4202 y = (int) y1 - (int) stringHeight / 2 + (int) (lineFactor * stringHeight); 4203 g2d.setColor(tg.get_FontBackColor()); 4204 g2d.clearRect(x, y, stringWidth, stringHeight); 4205 y = (int) y1 + (int) (stringHeight / 2) + (int) (lineFactor * stringHeight); 4206 g2d.setColor(tg.get_TextColor()); 4207 g2d.drawString(s, x, y); 4208 break; 4209 case screen: //for SCREEN, GUARD, COVER 4210 if (tg.Pixels.size() >= 14) { 4211 pt1 = tg.Pixels.get(3); 4212 pt2 = tg.Pixels.get(10); 4213 quadrant = lineutility.GetQuadrantDouble(pt1, pt2); 4214 theta = Math.atan2(pt2.y - pt1.y, pt2.x - pt1.x); 4215 switch (quadrant) { 4216 case 1: 4217 theta += Math.PI / 2; 4218 break; 4219 case 2: 4220 theta -= Math.PI / 2; 4221 break; 4222 case 3: 4223 theta -= Math.PI / 2; 4224 break; 4225 case 4: 4226 theta += Math.PI / 2; 4227 break; 4228 default: 4229 break; 4230 } 4231 4232 g2d.rotate(theta, x1, y1); 4233 stringWidth = metrics.stringWidth(s); 4234 stringHeight = font.getSize(); 4235 4236 x = (int) x1 - stringWidth / 2; 4237 y = (int) y1 - (int) stringHeight / 2 + (int) (lineFactor * stringHeight); 4238 g2d.setColor(tg.get_FontBackColor()); 4239 g2d.clearRect(x, y, stringWidth, stringHeight); 4240 y = (int) y1 + (int) (stringHeight / 2) + (int) (lineFactor * stringHeight); 4241 g2d.setColor(tg.get_TextColor()); 4242 g2d.drawString(s, x, y); 4243 } else { 4244 stringWidth = metrics.stringWidth(s); 4245 stringHeight = font.getSize(); 4246 x = (int) tg.Pixels.get(0).x;//(int) x1 - stringWidth / 2; 4247 y = (int) tg.Pixels.get(0).y;//(int) y1 - (int) stringHeight / 2 + (int) (lineFactor * stringHeight); 4248 g2d.setColor(tg.get_FontBackColor()); 4249 g2d.clearRect(x, y, stringWidth, stringHeight); 4250 y = (int) y + (int) (stringHeight / 2) + (int) (lineFactor * stringHeight); 4251 g2d.setColor(tg.get_TextColor()); 4252 g2d.drawString(s, x, y); 4253 } 4254 break; 4255 default: 4256 break; 4257 } //end switch 4258 } //end for 4259 } catch (Exception exc) { 4260 ErrorLogger.LogException(_className, "DisplayModifiers", 4261 new RendererException("Failed inside DisplayModifiers", exc)); 4262 } 4263 }//end function 4264 4265 /** 4266 * Returns a Shape object for the text background for labels and modifiers 4267 * 4268 * @param tg the tactical graphic object 4269 * @param pt0 1st point of segment 4270 * @param pt1 last point of segment 4271 * @param stringWidth string width 4272 * @param stringHeight string height 4273 * @param lineFactor number of text lines above or below the segment 4274 * @param isTextFlipped true if text is flipped 4275 * @return the modifier shape 4276 */ 4277 public static Shape2 BuildModifierShape( 4278 TGLight tg, 4279 POINT2 pt0, 4280 POINT2 pt1, 4281 int stringWidth, 4282 int stringHeight, 4283 double lineFactor, 4284 boolean isTextFlipped) { 4285 Shape2 modifierFill = null; 4286 try { 4287 4288 POINT2 ptTemp0 = new POINT2(pt0), ptTemp1 = new POINT2(pt1); 4289 4290 if (isTextFlipped) { 4291 lineFactor += 1; 4292 } 4293 4294 if (lineFactor < 0) //extend pt0,pt1 above the line 4295 { 4296 ptTemp0 = lineutility.ExtendDirectedLine(pt0, pt1, pt0, 2, -lineFactor * stringHeight); 4297 ptTemp1 = lineutility.ExtendDirectedLine(pt0, pt1, pt1, 2, -lineFactor * stringHeight); 4298 } 4299 if (lineFactor > 0) //extend pt0,pt1 below the line 4300 { 4301 ptTemp0 = lineutility.ExtendDirectedLine(pt0, pt1, pt0, 3, lineFactor * stringHeight); 4302 ptTemp1 = lineutility.ExtendDirectedLine(pt0, pt1, pt1, 3, lineFactor * stringHeight); 4303 } 4304 if (ptTemp0.y == ptTemp1.y) { 4305 ptTemp0.y += 1; 4306 } 4307 4308 POINT2 pt3 = null, pt4 = null, pt5 = null, pt6 = null, pt7 = null; 4309 pt3 = lineutility.ExtendAlongLineDouble(ptTemp0, ptTemp1, -stringWidth); 4310 pt4 = lineutility.ExtendDirectedLine(ptTemp1, ptTemp0, pt3, 0, stringHeight / 2); 4311 pt5 = lineutility.ExtendDirectedLine(ptTemp1, ptTemp0, pt3, 1, stringHeight / 2); 4312 pt6 = lineutility.ExtendDirectedLine(ptTemp1, ptTemp0, ptTemp0, 1, stringHeight / 2); 4313 pt7 = lineutility.ExtendDirectedLine(ptTemp1, ptTemp0, ptTemp0, 0, stringHeight / 2); 4314 modifierFill = new Shape2(Shape2.SHAPE_TYPE_MODIFIER_FILL); 4315 4316 modifierFill.moveTo(pt4); 4317 modifierFill.lineTo(pt5); 4318 modifierFill.lineTo(pt6); 4319 modifierFill.lineTo(pt7); 4320 modifierFill.lineTo(pt4); 4321 } catch (Exception exc) { 4322 ErrorLogger.LogException(_className, "BuildModifierShape", 4323 new RendererException("Failed inside BuildModifierShape", exc)); 4324 } 4325 return modifierFill; 4326 } 4327 4328 /** 4329 * For BOUNDARY and other line types which require breaks for the integral 4330 * text. Currently only boundary uses this 4331 * 4332 * @param tg 4333 * @param g2d the graphics object for drawing 4334 * @param shapes the shape array 4335 */ 4336 public static void GetIntegralTextShapes(TGLight tg, 4337 Graphics2D g2d, 4338 ArrayList<Shape2> shapes) { 4339 try { 4340 if (tg.Pixels == null || shapes == null) { 4341 return; 4342 } 4343 4344 HashMap<Integer, Color> hmap = clsUtility.getMSRSegmentColors(tg); 4345 Color color = null; 4346 4347 Shape2 shape = null; 4348 Shape2 segShape = null;//diangostic 1-22-13 4349 g2d.setFont(tg.get_Font()); 4350 int j = 0; 4351 String affiliation = null; 4352 FontMetrics metrics = g2d.getFontMetrics(); 4353 String echelonSymbol = null; 4354 int stringWidthEchelonSymbol = 0; 4355 //boolean lineTooShort = false; 4356 POINT2 ptEchelonStart = null, ptEchelonEnd = null, midpt, 4357 ptENY0Start = null, ptENY0End = null, ptENY1Start, ptENY1End, pt0 = null, pt1 = null; 4358 double dist = 0; 4359 BasicStroke stroke = null; 4360 switch (tg.get_LineType()) { 4361 case TacticalLines.BOUNDARY: 4362 echelonSymbol = tg.get_EchelonSymbol(); 4363 //shapes = new ArrayList(); 4364 shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE); 4365 shape.setLineColor(tg.get_LineColor()); 4366 shape.set_Style(tg.get_LineStyle()); 4367 stroke = clsUtility.getLineStroke(tg.get_LineThickness(), shape.get_Style(), tg.get_lineCap(), BasicStroke.JOIN_ROUND); 4368 shape.setStroke(stroke); 4369 if (echelonSymbol != null && !echelonSymbol.isEmpty()) { 4370 stringWidthEchelonSymbol = metrics.stringWidth(echelonSymbol); 4371 } 4372 //diagnostic 4373 if (hmap == null || hmap.isEmpty()) { 4374 shape.moveTo(tg.Pixels.get(0)); 4375 for (j = 1; j < tg.Pixels.size(); j++) { 4376 shape.lineTo(tg.Pixels.get(j)); 4377 } 4378 shapes.add(shape); 4379 break; 4380 } 4381 //end section 4382 int n = tg.Pixels.size(); 4383 //for (j = 0; j < tg.Pixels.size() - 1; j++) 4384 for (j = 0; j < n - 1; j++) { 4385 segShape = null; 4386 if (hmap != null) { 4387 if (hmap.containsKey(j)) { 4388 color = (Color) hmap.get(j); 4389 segShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE); 4390 segShape.setLineColor(color); 4391 segShape.set_Style(tg.get_LineStyle()); 4392 segShape.setStroke(stroke); 4393 } 4394 } 4395 4396 pt0 = tg.Pixels.get(j); 4397 pt1 = tg.Pixels.get(j + 1); 4398 //lineTooShort = GetBoundarySegmentTooShort(tg, g2d, j); 4399 if (segShape != null) { 4400 segShape.moveTo(pt0); 4401 } else { 4402 shape.moveTo(pt0); 4403 } 4404 4405 //uncoment comment to remove line breaks for GE 4406 //if (lineTooShort || tg.get_Client().equals("ge")) 4407 if (tg.get_Client().equals("ge") || GetBoundarySegmentTooShort(tg, g2d, j) == true) { 4408 if (segShape != null) { 4409 segShape.lineTo(pt1); 4410 shapes.add(segShape); 4411 continue; 4412 } else { 4413 shape.lineTo(pt1); 4414 continue; 4415 } 4416 } 4417 4418 midpt = lineutility.MidPointDouble(pt0, pt1, 0); 4419 if (segShape != null) { 4420 segShape.moveTo(pt0); 4421 } else { 4422 shape.moveTo(pt0); 4423 } 4424 4425 if (stringWidthEchelonSymbol > 0) { 4426 midpt = lineutility.MidPointDouble(pt0, pt1, 0); 4427 dist = lineutility.CalcDistanceDouble(pt0, midpt) - stringWidthEchelonSymbol / 1.5; 4428 ptEchelonStart = lineutility.ExtendAlongLineDouble(pt0, pt1, dist); 4429 dist = lineutility.CalcDistanceDouble(pt0, midpt) + stringWidthEchelonSymbol / 1.5; 4430 ptEchelonEnd = lineutility.ExtendAlongLineDouble(pt0, pt1, dist); 4431 if (segShape != null) { 4432 segShape.lineTo(ptEchelonStart); 4433 segShape.moveTo(ptEchelonEnd); 4434 } else { 4435 shape.lineTo(ptEchelonStart); 4436 shape.moveTo(ptEchelonEnd); 4437 } 4438 } 4439 if (segShape != null) { 4440 segShape.lineTo(pt1); 4441 } else { 4442 shape.lineTo(pt1); 4443 } 4444 if (segShape != null) { 4445 shapes.add(segShape); 4446 } 4447 }//end for 4448 shapes.add(shape); 4449 break; 4450 default: 4451 break; 4452 } 4453 } catch (Exception exc) { 4454 ErrorLogger.LogException(_className, "GetIntegralTextShapes", 4455 new RendererException("Failed inside GetIntegralTextShapes", exc)); 4456 } 4457 } 4458 4459 /** 4460 * Displays the modifiers to a Graphics2D from a BufferedImage 4461 * 4462 * @param tg the tactical graphic 4463 * @param g2d the Graphic for drawing 4464 * @param shapes the shape array 4465 * @param isTextFlipped true if text is flipped 4466 * @param converter to convert between geographic and pixel coordinates 4467 */ 4468 public static void DisplayModifiers2(TGLight tg, 4469 Graphics2D g2d, 4470 ArrayList<Shape2> shapes, 4471 boolean isTextFlipped, 4472 IPointConversion converter) { 4473 try { 4474 if (shapes == null) { 4475 return; 4476 } 4477 4478 if (tg.modifiers == null || tg.modifiers.isEmpty()) { 4479 return; 4480 } 4481 Font font = null; 4482 int j = 0; 4483 Modifier2 modifier = null; 4484 Color fontBackColor = tg.get_FontBackColor(); 4485 double theta = 0; 4486 double stringWidth = 0, stringHeight = 0; 4487 String s = ""; 4488 Bitmap image = null; 4489 int x = 0, y = 0; 4490 POINT2 pt0 = null, pt1 = null, pt2 = null, pt3 = null; 4491 int quadrant = -1; 4492 Shape2 shape2 = null; 4493 long lineType = tg.get_LineType(); 4494 font = tg.get_Font(); //might have to change this 4495 if (font == null) { 4496 font = g2d.getFont(); 4497 } 4498 if (font.getSize() == 0) { 4499 return; 4500 } 4501 g2d.setFont(font); 4502 FontMetrics metrics = g2d.getFontMetrics(); 4503 //we need a background color 4504 if (fontBackColor != null) { 4505 g2d.setBackground(fontBackColor); 4506 } else { 4507 g2d.setBackground(Color.white); 4508 } 4509 4510 Point2D anchor = null; 4511 Point2D anchorOffset = null; 4512 4513 int direction = -1; 4514 Point glyphPosition = null; 4515 for (j = 0; j < tg.modifiers.size(); j++) { 4516 modifier = (Modifier2) tg.modifiers.get(j); 4517 4518 double lineFactor = modifier.lineFactor; 4519 4520 if (isTextFlipped) { 4521 lineFactor = -lineFactor; 4522 } 4523 4524 s = modifier.text; 4525 if (s == null || s.equals("")) { 4526 4527 image = modifier.image; 4528 if (image == null) { 4529 continue; 4530 } 4531 } 4532 stringWidth = s != null ? (double) metrics.stringWidth(s) + 1 : image.getWidth() + 1; 4533 stringHeight = s != null ? (double) font.getSize() : image.getHeight(); 4534 4535 double x1 = 0, y1 = 0, x2 = 0, y2 = 0, dist = 0; 4536 pt0 = modifier.textPath[0]; 4537 x1 = Math.round(pt0.x); 4538 y1 = Math.round(pt0.y); 4539 pt1 = modifier.textPath[1]; 4540 x2 = Math.round(pt1.x); 4541 y2 = Math.round(pt1.y); 4542 theta = Math.atan2(y2 - y1, x2 - x1); 4543 POINT2 midPt; 4544 if (x1 > x2) { 4545 theta -= Math.PI; 4546 } 4547 pt0 = new POINT2(x1, y1); 4548 pt1 = new POINT2(x2, y2); 4549 midPt = new POINT2((x1 + x2) / 2, (y1 + y2) / 2); 4550 Point2D modifierPosition = null; //use this if using justify 4551 int justify = ShapeInfo.justify_left; 4552 switch (modifier.type) { 4553 case aboveEnd: // On line 4554 case toEnd: // Next to line 4555 if (x1 == x2) { 4556 x2 += 1; 4557 } 4558 4559 if (lineFactor >= 0) { 4560 direction = 2; 4561 } else { 4562 direction = 3; 4563 } 4564 4565 if (lineType == TacticalLines.LC || tg.get_Client().equalsIgnoreCase("ge")) { 4566 direction = lineutility.reverseDirection(direction); 4567 } 4568 4569 if ((modifier.type == toEnd && x1 < x2) || (modifier.type == aboveEnd && x2 < x1)) { 4570 justify = ShapeInfo.justify_right; 4571 } else { 4572 justify = ShapeInfo.justify_left; 4573 } 4574 4575 //3rd point value is location to start perpendicular line from 4576 pt3 = lineutility.ExtendDirectedLine(pt1, pt0, pt0, direction, lineFactor * stringHeight); 4577 //pt3 is the end point of the perpendicularline 4578 4579 glyphPosition = new Point((int) pt3.x, (int) pt3.y); 4580 modifierPosition = new Point2D.Double(pt3.x, pt3.y); 4581 4582 anchor = new Point2D.Double(pt0.x, pt0.y); 4583 anchorOffset = new Point2D.Double(pt3.x - pt0.x, pt3.y - pt0.y); 4584 4585 break; 4586 case aboveStartInside: 4587 //returns pt3 which is based on the specified distance from pt0 along the line of pt0 to pt1. 4588 pt3 = lineutility.ExtendAlongLineDouble(pt0, pt1, stringWidth); 4589 4590 glyphPosition = new Point((int) pt3.x, (int) pt3.y); 4591 modifierPosition = new Point2D.Double((int) pt3.x, pt3.y); 4592 4593 anchor = new Point2D.Double(pt0.x, pt0.y); 4594 anchorOffset = new Point2D.Double(pt3.x - pt0.x, pt3.y - pt0.y); 4595 break; 4596 case aboveEndInside: 4597 //returns pt3 which is based on the specified distance from pt0 along the line of pt1 to pt0. 4598 pt3 = lineutility.ExtendAlongLineDouble(pt1, pt0, stringWidth); 4599 4600 glyphPosition = new Point((int) pt3.x, (int) pt3.y); 4601 modifierPosition = new Point2D.Double((int) pt3.x, pt3.y); 4602 4603 anchor = new Point2D.Double(pt1.x, pt1.y); 4604 anchorOffset = new Point2D.Double(pt3.x - pt1.x, pt3.y - pt1.y); 4605 break; 4606 case aboveMiddle: 4607 case aboveMiddlePerpendicular: 4608 pt2 = midPt; 4609 anchor = new Point2D.Double(midPt.x,midPt.y); 4610 4611 if (tg.get_Client().equals("2D")) { 4612 lineFactor += 0.5; 4613 } 4614 4615 if (lineFactor >= 0) { 4616 pt3 = lineutility.ExtendDirectedLine(pt0, pt2, pt2, 3, Math.abs((lineFactor) * stringHeight)); 4617 midPt = lineutility.ExtendDirectedLine(pt0, midPt, midPt, 3, Math.abs((lineFactor) * stringHeight)); 4618 } else { 4619 pt3 = lineutility.ExtendDirectedLine(pt0, pt2, pt2, 2, Math.abs((lineFactor) * stringHeight)); 4620 midPt = lineutility.ExtendDirectedLine(pt0, midPt, midPt, 2, Math.abs((lineFactor) * stringHeight)); 4621 } 4622 //pt3=lineutility.ExtendDirectedLine(pt0, pt2, pt2, 2, lineFactor*stringHeight); 4623 if (x1 == x2 && y1 > y2) { 4624 pt3 = lineutility.ExtendDirectedLine(pt0, pt2, pt2, 1, Math.abs((lineFactor) * stringHeight)); 4625 midPt = lineutility.ExtendDirectedLine(pt0, midPt, midPt, 1, Math.abs((lineFactor) * stringHeight)); 4626 } 4627 if (x1 == x2 && y1 < y2) { 4628 pt3 = lineutility.ExtendDirectedLine(pt0, pt2, pt2, 0, Math.abs((lineFactor) * stringHeight)); 4629 midPt = lineutility.ExtendDirectedLine(pt0, midPt, midPt, 0, Math.abs((lineFactor) * stringHeight)); 4630 } 4631 4632 glyphPosition = new Point((int) pt3.x, (int) pt3.y); 4633 justify = ShapeInfo.justify_center; 4634 modifierPosition = new Point2D.Double(midPt.x, midPt.y); 4635 4636 //anchor = new Point2D.Double(midPt.x, midPt.y); 4637 anchorOffset = new Point2D.Double(midPt.x - anchor.getX(), midPt.y - anchor.getY()); 4638 4639 if(modifier.type == aboveMiddlePerpendicular) { 4640 // Need to negate the original rotation 4641 if (x1 > x2) { 4642 theta += Math.PI; 4643 } 4644 // Adjust the label rotation based on the y values 4645 if (y1 > y2) { 4646 theta += Math.PI; 4647 } 4648 // Rotate by 90 degrees. This is how we rotate the label perpendicular to the line 4649 theta -= Math.PI / 2; 4650 } 4651 break; 4652 case area: 4653 theta = 0; 4654 4655 //y = (int) y1 + (int) (stringHeight / 2) + (int) (1.25 * lineFactor * stringHeight); 4656 y = (int) y1 + (int) (stringHeight / 2) + (int) (lineFactor * stringHeight); 4657 x = image != null ? (int) (x1 - stringWidth / 3) : (int) x1; 4658 4659 glyphPosition = new Point(x, y); 4660 justify = ShapeInfo.justify_center; 4661 modifierPosition = new Point2D.Double(x, y); 4662 4663 anchor = new Point2D.Double(x1, y1); 4664 anchorOffset = new Point2D.Double(x - x1, y - y1); 4665 break; 4666 case areaImage: 4667 glyphPosition = new Point((int)x1, (int)y1); 4668 justify = ShapeInfo.justify_center; 4669 modifierPosition = new Point2D.Double((int)x1, (int)y1); 4670 4671 anchor = new Point2D.Double(x1, y1); 4672 anchorOffset = new Point2D.Double(0, 0); 4673 break; 4674 case screen: //for SCREEN, GUARD, COVER, not currently used 4675 if (tg.Pixels.size() >= 14) { 4676 pt1 = tg.Pixels.get(3); 4677 pt2 = tg.Pixels.get(10); 4678 quadrant = lineutility.GetQuadrantDouble(pt1, pt2); 4679 theta = Math.atan2(pt2.y - pt1.y, pt2.x - pt1.x); 4680 if (Math.abs(theta) < Math.PI / 8) { 4681 if (theta < 0) { 4682 theta -= Math.PI / 2; 4683 } else { 4684 theta += Math.PI / 2; 4685 } 4686 } 4687 switch (quadrant) { 4688 case 1: 4689 theta += Math.PI / 2; 4690 break; 4691 case 2: 4692 theta -= Math.PI / 2; 4693 break; 4694 case 3: 4695 theta -= Math.PI / 2; 4696 break; 4697 case 4: 4698 theta += Math.PI / 2; 4699 break; 4700 default: 4701 break; 4702 } 4703 4704 x = (int) x1 - (int) stringWidth / 2; 4705 y = (int) y1 - (int) stringHeight / 2 + (int) (lineFactor * stringHeight); 4706 y = (int) y1 + (int) (stringHeight / 2) + (int) (lineFactor * stringHeight); 4707 anchor = new Point2D.Double(x1, y1); 4708 } else { 4709 theta = 0; 4710 x = (int) tg.Pixels.get(0).x; 4711 y = (int) tg.Pixels.get(0).y; 4712 anchor = new Point2D.Double(x, y); 4713 x = (int) x - (int) stringWidth / 2; 4714 y = (int) y - (int) stringHeight / 2 + (int) (lineFactor * stringHeight); 4715 y = (int) y + (int) (stringHeight / 2) + (int) (lineFactor * stringHeight); 4716 } 4717 4718 glyphPosition = new Point(x, y); 4719 //glyphPosition=new Point2D.Double(x,y); 4720 //anchor = new Point2D.Double(x1, y1); 4721 anchorOffset = new Point2D.Double(x - anchor.getX(), y - anchor.getY()); 4722 break; 4723 default: 4724 break; 4725 } //end switch 4726 4727 shape2 = new Shape2(Shape2.SHAPE_TYPE_MODIFIER_FILL); 4728 4729 shape2.setStroke(new BasicStroke(0, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 3)); 4730 4731 if (tg.get_TextColor() != null) { 4732 shape2.setFillColor(tg.get_TextColor()); 4733 } else if (tg.get_LineColor() != null) { 4734 shape2.setFillColor(tg.get_LineColor()); 4735 } 4736 if (tg.get_LineColor() != null) { 4737 shape2.setLineColor(tg.get_LineColor()); 4738 } 4739 //only GE uses the converter, generic uses the affine transform and draws at 0,0 4740 if (converter != null) { 4741 shape2.setGlyphPosition(glyphPosition); 4742 } else { 4743 shape2.setGlyphPosition(new Point2D.Double(0, 0)); 4744 } 4745 //shape2.setGlyphPosition(new Point(0,0)); 4746 //added two settings for use by GE 4747 if(s != null && !s.equals("")) { 4748 shape2.setModifierString(s); 4749 TextLayout tl = new TextLayout(s, font, g2d.getFontMetrics().getFontRenderContext()); 4750 shape2.setTextLayout(tl); 4751 shape2.setTextJustify(justify); 4752 } else if (image != null) { 4753 shape2.setModifierImage(image); 4754 } 4755 //shape2.setModifierStringPosition(glyphPosition);//M. Deutch 7-6-11 4756 shape2.setModifierAngle(theta * 180 / Math.PI); 4757 shape2.setModifierPosition(modifierPosition); 4758 shape2.setModifierAnchor(anchor); 4759 shape2.setModifierAnchorOffset(anchorOffset); 4760 4761 if (shape2 != null) { 4762 shapes.add(shape2); 4763 } 4764 4765 } //end for 4766 } //end try 4767 catch (Exception exc) { 4768 ErrorLogger.LogException(_className, "DisplayModifiers2", 4769 exc); 4770 } 4771 }//end function 4772 4773 /** 4774 * Builds a shape object to wrap text 4775 * 4776 * @param g2d the Graphic object for drawing 4777 * @param str text to wrap 4778 * @param font the draw font 4779 * @param tx the drawing transform, text rotation and translation 4780 * @return 4781 */ 4782 public static Shape getTextShape(Graphics2D g2d, 4783 String str, 4784 Font font, 4785 AffineTransform tx) { 4786 TextLayout tl = null; 4787 FontRenderContext frc = null; 4788 try { 4789 frc = g2d.getFontRenderContext(); 4790 tl = new TextLayout(str, font, frc); 4791 } catch (Exception exc) { 4792 ErrorLogger.LogException(_className, "getTextShape", 4793 new RendererException("Failed inside getTextShape", exc)); 4794 } 4795 return tl.getOutline(tx); 4796 } 4797 4798 /** 4799 * Creates text outline as a shape 4800 * 4801 * @param originalText the original text 4802 * @return text shape 4803 */ 4804 public static Shape2 createTextOutline(Shape2 originalText) { 4805 Shape2 siOutline = null; 4806 try { 4807 Shape outline = originalText.getShape(); 4808 4809 siOutline = new Shape2(Shape2.SHAPE_TYPE_MODIFIER_FILL); 4810 siOutline.setShape(outline); 4811 4812 if (originalText.getFillColor().getRed() == 255 4813 && originalText.getFillColor().getGreen() == 255 4814 && originalText.getFillColor().getBlue() == 255) { 4815 siOutline.setLineColor(Color.BLACK); 4816 } else { 4817 siOutline.setLineColor(Color.WHITE); 4818 } 4819 4820 int width = RendererSettings.getInstance().getTextOutlineWidth(); 4821 4822 siOutline.setStroke(new BasicStroke(width, BasicStroke.CAP_ROUND, 4823 BasicStroke.JOIN_ROUND, 3)); 4824 4825 } catch (Exception exc) { 4826 ErrorLogger.LogException(_className, "createTextOutline", 4827 new RendererException("Failed inside createTextOutline", exc)); 4828 } 4829 return siOutline; 4830 } 4831 4832 /** 4833 * Channels don't return points in tg.Pixels. For Channels modifiers we only 4834 * need to collect the points, don't need internal arrays, and can calculate 4835 * on which segments the modifiers lie. 4836 * 4837 * @param shape 4838 * @return 4839 */ 4840 private static ArrayList<POINT2> getShapePoints(Shape shape) { 4841 try { 4842 ArrayList<Point2D> ptsPoly = new ArrayList(); 4843 Point2D ptPoly = null; 4844 double[] coords = new double[6]; 4845 int zeros = 0; 4846 for (PathIterator i = shape.getPathIterator(null); !i.isDone(); i.next()) { 4847 int type = i.currentSegment(coords); 4848 if (type == 0 && zeros == 2) { 4849 break; 4850 } 4851 switch (type) { 4852 case PathIterator.SEG_MOVETO: 4853 ptPoly = new Point2D.Double(coords[0], coords[1]); 4854 ptsPoly.add(ptPoly); 4855 zeros++; 4856 break; 4857 case PathIterator.SEG_LINETO: 4858 ptPoly = new Point2D.Double(coords[0], coords[1]); 4859 ptsPoly.add(ptPoly); 4860 break; 4861 case PathIterator.SEG_QUADTO: //quadTo was never used 4862 break; 4863 case PathIterator.SEG_CUBICTO: //curveTo was used for some METOC's 4864 break; 4865 case PathIterator.SEG_CLOSE: //closePath was never used 4866 break; 4867 } 4868 } 4869 if (ptsPoly.size() > 0) { 4870 ArrayList<POINT2> pts = null; 4871 pts = new ArrayList(); 4872 for (int j = 0; j < ptsPoly.size(); j++) { 4873 Point2D pt2d = ptsPoly.get(j); 4874 POINT2 pt = new POINT2(pt2d.getX(), pt2d.getY()); 4875 pts.add(pt); 4876 } 4877 return pts; 4878 } 4879 } catch (Exception exc) { 4880 ErrorLogger.LogException(_className, "getshapePoints", 4881 new RendererException("Failed inside getShapePoints", exc)); 4882 } 4883 return null; 4884 } 4885 4886 private static Bitmap getImageModifier(TGLight tg) { 4887 String symbolID = tg.get_SymbolId(); 4888 ImageInfo symbol = null; 4889 Map<String,String> mods = new HashMap<>(); 4890 Map<String,String> sa = new HashMap<>(); 4891 sa.put(MilStdAttributes.PixelSize, String.valueOf(tg.get_IconSize())); 4892 int contaminationCode = EntityCode.getSymbolForContaminationArea(SymbolID.getEntityCode(symbolID)); 4893 int modifier1Code = SymbolID.getModifier1(symbolID); 4894 int lineType = GetLinetypeFromString(symbolID); 4895 if (contaminationCode > 0) { 4896 sa.put(MilStdAttributes.OutlineSymbol, "true"); 4897 sa.put(MilStdAttributes.FillColor, RendererUtilities.colorToHexString(tg.get_FillColor(), true)); 4898 sa.put(MilStdAttributes.LineColor, RendererUtilities.colorToHexString(tg.get_LineColor(), true)); 4899 String contaminationSP = SymbolID.setEntityCode(symbolID, contaminationCode); 4900 contaminationSP = SymbolID.setHQTFD(contaminationSP, 0); // Remove dummy modifier if necessary 4901 symbol = SinglePointRenderer.getInstance().RenderSP(contaminationSP, mods, sa); 4902 } else if (lineType == TacticalLines.DEPICT || lineType == TacticalLines.MINED || lineType == TacticalLines.FENCED || lineType == TacticalLines.MINE_LINE) { 4903 if (modifier1Code < 13 || modifier1Code > 50) { 4904 // Invalid mine type 4905 modifier1Code = 13;//unspecified mine (default value if not specified as per MilStd 2525) 4906 symbolID = SymbolID.setModifier1(symbolID, modifier1Code); 4907 } 4908 if (tg.get_KeepUnitRation()) { 4909 sa.put(MilStdAttributes.PixelSize, String.valueOf((int) (tg.get_IconSize() * 1.5))); 4910 } 4911 sa.put(MilStdAttributes.OutlineSymbol, "true"); 4912 symbol = SinglePointRenderer.getInstance().RenderModifier(symbolID, sa); 4913 } else if (lineType == TacticalLines.LAA && modifier1Code > 0) { 4914 sa.put(MilStdAttributes.OutlineSymbol, "true"); 4915 sa.put(MilStdAttributes.FillColor, RendererUtilities.colorToHexString(tg.get_FillColor(), true)); 4916 sa.put(MilStdAttributes.LineColor, RendererUtilities.colorToHexString(tg.get_LineColor(), true)); 4917 if (tg.get_KeepUnitRation()) { 4918 sa.put(MilStdAttributes.PixelSize, String.valueOf((int) (tg.get_IconSize() * 1.5))); 4919 } 4920 symbol = SinglePointRenderer.getInstance().RenderModifier(symbolID, sa); 4921 } 4922 else if (lineType == TacticalLines.DECISION_LINE) { 4923 4924 sa.put(MilStdAttributes.PixelSize, String.valueOf((int) (tg.get_IconSize() * 1.5))); 4925 sa.put(MilStdAttributes.KeepUnitRatio, String.valueOf((tg.get_KeepUnitRation()))); 4926 sa.put(MilStdAttributes.FillColor, RendererUtilities.colorToHexString(tg.get_FillColor(), true)); 4927 sa.put(MilStdAttributes.LineColor, RendererUtilities.colorToHexString(tg.get_LineColor(), true)); 4928 sa.put(MilStdAttributes.OutlineSymbol, "false"); 4929 mods.put(Modifiers.T_UNIQUE_DESIGNATION_1, (tg.get_Name())); 4930 4931 String decisionPoint = SymbolID.setEntityCode(symbolID, EntityCode.EntityCode_Decision_Point); 4932 symbol = SinglePointRenderer.getInstance().RenderSP(decisionPoint, mods, sa); 4933 } 4934 else if (lineType == TacticalLines.ANCHORAGE_LINE || lineType == TacticalLines.ANCHORAGE_AREA) { 4935 sa.put(MilStdAttributes.OutlineSymbol, "false"); 4936 String anchorPoint = SymbolID.setEntityCode(symbolID, EntityCode.EntityCode_AnchoragePoint); 4937 symbol = SinglePointRenderer.getInstance().RenderSP(anchorPoint, mods, sa); 4938 } 4939 4940 if (symbol != null) 4941 return symbol.getImage(); 4942 else 4943 return null; 4944 } 4945 4946 private static String removeDecimal(double doubleVal) { 4947 return String.valueOf(Math.round(doubleVal)); 4948 } 4949 4950 private static String removeDecimal(String strDoubleVal) { 4951 if (strDoubleVal.indexOf(" ") > 0) // String contains unit 4952 return removeDecimal(Double.parseDouble(strDoubleVal.substring(0, strDoubleVal.indexOf(" ")))) + strDoubleVal.substring(strDoubleVal.indexOf(" ")); 4953 else 4954 return removeDecimal(Double.parseDouble(strDoubleVal)); 4955 } 4956}