001/* 002 * To change this template, choose Tools | Templates 003 * and open the template in the editor. 004 */ 005 006package armyc2.c5isr.RenderMultipoints; 007import static armyc2.c5isr.JavaTacticalRenderer.clsUtility.isAutoshape; 008 009import armyc2.c5isr.graphics2d.Area; 010import armyc2.c5isr.graphics2d.BasicStroke; 011import armyc2.c5isr.graphics2d.Rectangle; 012import armyc2.c5isr.renderer.PatternFillRenderer; 013import armyc2.c5isr.renderer.utilities.IPointConversion; 014import armyc2.c5isr.JavaTacticalRenderer.TGLight; 015import armyc2.c5isr.JavaLineArray.TacticalLines; 016import armyc2.c5isr.JavaLineArray.lineutility; 017import armyc2.c5isr.JavaLineArray.POINT2; 018import java.util.ArrayList; 019import armyc2.c5isr.renderer.utilities.ErrorLogger; 020import armyc2.c5isr.renderer.utilities.RendererException; 021import armyc2.c5isr.JavaLineArray.Shape2; 022 023import android.graphics.BitmapShader; 024import android.graphics.Shader; 025import armyc2.c5isr.renderer.utilities.Color; 026import armyc2.c5isr.renderer.utilities.ShapeInfo; 027import armyc2.c5isr.graphics2d.Point; 028import armyc2.c5isr.graphics2d.Point2D; 029import armyc2.c5isr.graphics2d.Rectangle2D; 030 031/** 032 * Server general utility class 033* 034 */ 035public final class clsUtility { 036 private static final String _className="clsUtility"; 037 public static final int Hatch_ForwardDiagonal=2; 038 public static final int Hatch_BackwardDiagonal=3; 039 public static final int Hatch_Vertical=4; 040 public static final int Hatch_Horizontal=5; 041 public static final int Hatch_Cross=8; 042 043 /** 044 * Adds hatch fill to shapes via PatternFillRendererD.MakeHatchPatternFill() or buildHatchFill() 045 * @param tg 046 * @param shapes 047 */ 048 protected static void addHatchFills(TGLight tg, ArrayList<ShapeInfo>shapes) 049 { 050 try 051 { 052 if(shapes==null || shapes.size()==0) 053 return; 054 055 int lineType=tg.get_LineType(); 056 int hatchStyle=tg.get_FillStyle(); 057 int j=0,hatch2=0; 058 Shape2 shape2=null; 059 int index=0; 060 float hatchLineThickness = 1.5f + ((tg.get_LineThickness() / 2f) - 1.5f) * (float) tg.get_patternScale(); 061 Color hatchColor = tg.get_LineColor(); 062 int hatchSpacing = (int) (hatchLineThickness * 10); 063 064// if(armyc2.c5isr.JavaTacticalRenderer.clsUtility.isClosedPolygon(lineType)==false) 065// if(armyc2.c5isr.JavaTacticalRenderer.clsUtility.IsChange1Area(lineType, null)==false) 066// return; 067 if(armyc2.c5isr.JavaTacticalRenderer.clsUtility.isClosedPolygon(lineType)==false) 068 { 069 if(armyc2.c5isr.JavaTacticalRenderer.clsUtility.IsChange1Area(lineType)==false) 070 { 071 switch(lineType) 072 { 073 case TacticalLines.BBS_AREA: 074 case TacticalLines.BBS_LINE: 075 case TacticalLines.BBS_RECTANGLE: 076 break; 077 default: 078 return; 079 } 080 } 081 } 082 083 switch(lineType) 084 { 085 case TacticalLines.NFA: 086 case TacticalLines.NFA_CIRCULAR: 087 case TacticalLines.NFA_RECTANGULAR: 088 case TacticalLines.LAA: 089 hatchStyle = Hatch_BackwardDiagonal; 090 break; 091 case TacticalLines.BIO: 092 case TacticalLines.NUC: 093 case TacticalLines.CHEM: 094 case TacticalLines.RAD: 095 hatchStyle=Hatch_BackwardDiagonal; 096 hatchColor = Color.yellow; 097 hatchLineThickness = 3 + (tg.get_LineThickness() - 3) * (float) tg.get_patternScale(); 098 break; 099 case TacticalLines.WFZ_REVD: 100 case TacticalLines.WFZ: 101 hatchStyle=Hatch_BackwardDiagonal; 102 if (tg.get_LineColor() == Color.BLACK) 103 hatchColor = Color.GRAY; 104 hatchSpacing /= 2; 105 break; 106 case TacticalLines.OBSAREA: 107 //CPOF client required adding a simple shape for 108 //setting texturepaint which WebRenderer does not use 109 for(j=0;j<shapes.size();j++) 110 { 111 ShapeInfo shape=shapes.get(j); 112 Color color=shape.getLineColor(); 113 if(color==null) 114 continue; 115 //if(shape.getLineColor().getRGB()==0) 116 if(shape.getLineColor().toARGB()==0) 117 shapes.remove(j); 118 } 119 hatchStyle = Hatch_BackwardDiagonal; 120 hatchSpacing *= 1.25; 121 break; 122 default: 123 if(hatchStyle<=0) 124 return; 125 break; 126 } 127 //get the index of the shape with the same fillstyle 128 int n=shapes.size(); 129 //for(j=0;j<shapes.size();j++) 130 for(j=0;j<n;j++) 131 { 132 shape2=(Shape2)shapes.get(j); 133 hatch2=shape2.get_FillStyle(); 134 if(hatch2==hatchStyle) 135 { 136 index=j; 137 break; 138 } 139 } 140 n=shapes.size(); 141 //for(int k=0;k<shapes.size();k++) 142 for(int k=0;k<n;k++) 143 { 144 //the outline should always be the 0th shape for areas 145 ShapeInfo shape=null; 146 if(lineType==TacticalLines.RANGE_FAN || lineType==TacticalLines.RANGE_FAN_SECTOR || lineType==TacticalLines.RADAR_SEARCH) 147 { 148 shape=shapes.get(k); 149 shape2=(Shape2)shapes.get(k); 150 hatchStyle=shape2.get_FillStyle(); 151 } 152 else 153 shape=shapes.get(index); 154 155 if(hatchStyle<Hatch_ForwardDiagonal)//Hatch_ForwardDiagonal is the 0th hatch element 156 continue; 157 158 if (tg.get_UseHatchFill()) 159 { 160 shape.setPatternFillImage(PatternFillRenderer.MakeHatchPatternFill(hatchStyle, hatchSpacing, (int) hatchLineThickness, hatchColor)); 161 shape.setShader(new BitmapShader(shape.getPatternFillImage(), Shader.TileMode.REPEAT, Shader.TileMode.REPEAT)); 162 } 163 else if(hatchStyle != Hatch_Cross) 164 { 165 Shape2 shape3= buildHatchArea(tg, shape,hatchStyle, hatchSpacing); 166 //shape.setStroke(new BasicStroke(1)); 167 shape3.setStroke(new BasicStroke(hatchLineThickness)); 168 shape3.setLineColor(hatchColor); 169 shapes.add(shape3); 170 } 171 else //cross hatch 172 { 173 Shape2 shapeBk= buildHatchArea(tg, shape,Hatch_BackwardDiagonal,hatchSpacing); 174 Shape2 shapeFwd= buildHatchArea(tg, shape,Hatch_ForwardDiagonal,hatchSpacing); 175 //shapeBk.setStroke(new BasicStroke(1)); 176 shapeBk.setStroke(new BasicStroke(hatchLineThickness)); 177 shapeBk.setLineColor(hatchColor); 178 shapes.add(shapeBk); 179 //shapeFwd.setStroke(new BasicStroke(1)); 180 shapeFwd.setStroke(new BasicStroke(hatchLineThickness)); 181 shapeFwd.setLineColor(hatchColor); 182 shapes.add(shapeFwd); 183 } 184 if(lineType != TacticalLines.RANGE_FAN && lineType != TacticalLines.RANGE_FAN_SECTOR && lineType != TacticalLines.RADAR_SEARCH) 185 break; 186 } 187 } 188 catch (Exception exc) { 189 ErrorLogger.LogException(_className, "addHatchFills", 190 new RendererException("Failed inside addHatchFills", exc)); 191 } 192 } 193 194 /** 195 * Build Hatch fill. Does not use texture paint or shader. 196 * @param tg 197 * @param shape 198 * @param hatchStyle 199 * @return 200 */ 201 protected static Shape2 buildHatchArea(TGLight tg, ShapeInfo shape, int hatchStyle, double spacing) 202 { 203 Shape2 hatchLineShape=null; 204 try 205 { 206 hatchLineShape=new Shape2(Shape2.SHAPE_TYPE_POLYLINE); 207 Area hatchLineArea=null; 208 Rectangle rect=shape.getBounds(); 209 double x0=rect.getX(); 210 double y0=rect.getY(); 211 double width=rect.getWidth(); 212 double height=rect.getHeight(); 213 //we need a square 214 if(width>height) 215 height=width; 216 else 217 width=height; 218 219 //diagnostic 220 if(tg.get_UseHatchFill()) 221 { 222// hatchLineShape.moveTo(new POINT2(x0,y0)); 223// hatchLineShape.lineTo(new POINT2(x0+width,y0)); 224// hatchLineShape.lineTo(new POINT2(x0+width,y0+width)); 225// hatchLineShape.lineTo(new POINT2(x0,y0+width)); 226 hatchLineShape.set_Fillstyle(hatchStyle); 227// hatchLineShape.lineTo(new POINT2(x0,y0)); 228// Area shapeArea=new Area(shape.getShape()); 229// hatchLineArea=new Area(hatchLineShape.getShape()); 230// //intersect the hatch lines with the original shape area to get the fill 231// hatchLineArea.intersect(shapeArea); 232// hatchLineShape.setShape(hatchLineArea); 233 hatchLineShape.setShape(lineutility.createStrokedShape(shape.getShape())); 234 return hatchLineShape; 235 } 236 //end section 237 238 width *= 2; 239 height *= 2; 240 //the next two values should be equal 241 int horizLimit=0; 242 int vertLimit=0; 243 int j=0; 244 ArrayList<POINT2>vertPts=new ArrayList(); 245 ArrayList<POINT2>horizPts=new ArrayList(); 246 POINT2 vertPt=null,horizPt=null; 247 if(hatchStyle==Hatch_BackwardDiagonal) 248 { 249 horizLimit=(int)(width/spacing); 250 vertLimit=(int)(height/spacing); 251 for(j=0;j<vertLimit;j++) 252 { 253 vertPt=new POINT2(x0,y0+spacing*j); 254 vertPts.add(vertPt); 255 } 256 for(j=0;j<horizLimit;j++) 257 { 258 horizPt=new POINT2(x0+spacing*j,y0); 259 horizPts.add(horizPt); 260 } 261 262 hatchLineShape.moveTo(new POINT2(x0-spacing/2,y0-spacing/2)); 263 hatchLineShape.lineTo(new POINT2(x0,y0)); 264 for(j=0;j<vertLimit;j++) 265 { 266 if(j%2==0) 267 { 268 hatchLineShape.lineTo(vertPts.get(j)); 269 hatchLineShape.lineTo(horizPts.get(j)); 270 } 271 else 272 { 273 hatchLineShape.lineTo(horizPts.get(j)); 274 hatchLineShape.lineTo(vertPts.get(j)); 275 } 276 } 277 //go outside the bottom right corner to complete a valid area 278 hatchLineShape.lineTo(new POINT2(x0+width+spacing/2,y0+height+spacing/2)); 279 hatchLineShape.lineTo(new POINT2(x0+width+spacing,y0+height+spacing/2)); 280 hatchLineShape.lineTo(new POINT2(x0+width+spacing,y0-spacing/2)); 281 hatchLineShape.lineTo(new POINT2(x0-spacing/2,y0-spacing/2)); 282 } 283 if(hatchStyle==Hatch_ForwardDiagonal) 284 { 285 horizLimit=(int)(width/spacing); 286 vertLimit=(int)(height/spacing); 287 width /= 2; 288 for(j=0;j<vertLimit;j++) 289 { 290 vertPt=new POINT2(x0+width,y0+spacing*j); 291 vertPts.add(vertPt); 292 } 293 for(j=0;j<horizLimit;j++) 294 { 295 horizPt=new POINT2(x0+width-spacing*j,y0); 296 horizPts.add(horizPt); 297 } 298 299 hatchLineShape.moveTo(new POINT2(x0+width+spacing/2,y0-spacing/2)); 300 hatchLineShape.lineTo(new POINT2(x0,y0)); 301 for(j=0;j<vertLimit;j++) 302 { 303 if(j%2==0) 304 { 305 hatchLineShape.lineTo(vertPts.get(j)); 306 hatchLineShape.lineTo(horizPts.get(j)); 307 } 308 else 309 { 310 hatchLineShape.lineTo(horizPts.get(j)); 311 hatchLineShape.lineTo(vertPts.get(j)); 312 } 313 } 314 //go outside the bottom left corner to complete a valid area 315 hatchLineShape.lineTo(new POINT2(x0-spacing/2,y0+height+spacing/2)); 316 hatchLineShape.lineTo(new POINT2(x0-spacing,y0+height+spacing/2)); 317 hatchLineShape.lineTo(new POINT2(x0-spacing,y0-spacing/2)); 318 hatchLineShape.lineTo(new POINT2(x0+width+spacing/2,y0-spacing/2)); 319 } 320 if(hatchStyle==Hatch_Vertical) 321 { 322 horizLimit=(int)(width/(spacing/2)); 323 vertLimit=(int)(height/(spacing/2)); 324 for(j=0;j<horizLimit;j++) 325 { 326 if(j%2==0) 327 { 328 vertPt=new POINT2(x0+spacing/2*j,y0); 329 vertPts.add(vertPt); 330 vertPt=new POINT2(x0+spacing/2*j,y0+height); 331 vertPts.add(vertPt); 332 } 333 else 334 { 335 vertPt=new POINT2(x0+spacing/2*j,y0+height); 336 vertPts.add(vertPt); 337 vertPt=new POINT2(x0+spacing/2*j,y0); 338 vertPts.add(vertPt); 339 } 340 } 341 hatchLineShape.moveTo(new POINT2(x0-spacing/2,y0-spacing/2)); 342 hatchLineShape.lineTo(new POINT2(x0,y0)); 343 for(j=0;j<vertLimit-1;j++) 344 { 345 hatchLineShape.lineTo(vertPts.get(j)); 346 } 347 //go outside the bottom right corner to complete a valid area 348 hatchLineShape.lineTo(new POINT2(x0+width+spacing/2,y0+height+spacing/2)); 349 hatchLineShape.lineTo(new POINT2(x0+width+spacing,y0+height+spacing/2)); 350 hatchLineShape.lineTo(new POINT2(x0+width+spacing,y0-spacing/2)); 351 hatchLineShape.lineTo(new POINT2(x0-spacing/2,y0-spacing/2)); 352 } 353 if(hatchStyle==Hatch_Horizontal) 354 { 355 horizLimit=(int)(width/(spacing/2)); 356 vertLimit=(int)(height/(spacing/2)); 357 for(j=0;j<vertLimit;j++) 358 { 359 if(j%2==0) 360 { 361 horizPt=new POINT2(x0,y0+spacing/2*j); 362 horizPts.add(horizPt); 363 horizPt=new POINT2(x0+width,y0+spacing/2*j); 364 horizPts.add(horizPt); 365 } 366 else 367 { 368 horizPt=new POINT2(x0+width,y0+spacing/2*j); 369 horizPts.add(horizPt); 370 horizPt=new POINT2(x0,y0+spacing/2*j); 371 horizPts.add(horizPt); 372 } 373 } 374 hatchLineShape.moveTo(new POINT2(x0-spacing/2,y0-spacing/2)); 375 hatchLineShape.lineTo(new POINT2(x0,y0)); 376 for(j=0;j<vertLimit-1;j++) 377 { 378 hatchLineShape.lineTo(horizPts.get(j)); 379 } 380 //go outside the bottom left corner to complete a valid area 381 hatchLineShape.lineTo(new POINT2(x0-spacing/2,y0+height+spacing/2)); 382 hatchLineShape.lineTo(new POINT2(x0-spacing,y0+height+spacing/2)); 383 hatchLineShape.lineTo(new POINT2(x0-spacing,y0-spacing/2)); 384 hatchLineShape.lineTo(new POINT2(x0+width+spacing/2,y0-spacing/2)); 385 } 386 387 Area shapeArea=new Area(shape.getShape()); 388 hatchLineArea=new Area(hatchLineShape.getShape()); 389 //intersect the hatch lines with the original shape area to get the fill 390 hatchLineArea.intersect(shapeArea); 391 hatchLineShape.setShape(hatchLineArea); 392 //return null; 393 } 394 catch(Exception exc) 395 { 396 ErrorLogger.LogException(_className, "buildHatchArea", 397 new RendererException("Failed inside buildHatchArea", exc)); 398 } 399 return hatchLineShape; 400 } 401 402 protected static Point POINT2ToPoint(POINT2 pt2) 403 { 404 Point pt=new Point(); 405 pt.x=(int)pt2.x; 406 pt.y=(int)pt2.y; 407 return pt; 408 } 409 protected static POINT2 PointToPOINT2(Point pt) 410 { 411 POINT2 pt2=new POINT2(pt.x,pt.y); 412 return pt2; 413 } 414 protected static Point2D.Double POINT2ToPoint2D(POINT2 pt2) 415 { 416 Point2D.Double pt2d=new Point2D.Double(pt2.x,pt2.y); 417 return pt2d; 418 } 419 protected static ArrayList<POINT2> Points2DToPOINT2(ArrayList<Point2D>pts2d) 420 { 421 ArrayList<POINT2>pts=new ArrayList(); 422 POINT2 pt=null; 423 int n=pts2d.size(); 424 //for(int j=0;j<pts2d.size();j++) 425 for(int j=0;j<n;j++) 426 { 427 pt=new POINT2(pts2d.get(j).getX(),pts2d.get(j).getY()); 428 pts.add(pt); 429 } 430 return pts; 431 } 432 protected static POINT2 Point2DToPOINT2(Point2D pt2d) 433 { 434 POINT2 pt2=new POINT2(pt2d.getX(),pt2d.getY()); 435 return pt2; 436 } 437 /** 438 * @deprecated 439 * @param tg 440 * @return 441 */ 442 protected static boolean addModifiersBeforeClipping(TGLight tg) 443 { 444 boolean result=false; 445 int linetype=tg.get_LineType(); 446 switch(linetype) 447 { 448 case TacticalLines.TORPEDO: 449 case TacticalLines.OPTICAL: 450 case TacticalLines.ELECTRO: 451 case TacticalLines.BEARING_EW: 452 case TacticalLines.ACOUSTIC: 453 case TacticalLines.ACOUSTIC_AMB: 454 case TacticalLines.BEARING: 455 case TacticalLines.BEARING_J: 456 case TacticalLines.BEARING_RDF: 457 case TacticalLines.MSR: 458 case TacticalLines.MSR_ONEWAY: 459 case TacticalLines.MSR_TWOWAY: 460 case TacticalLines.MSR_ALT: 461 case TacticalLines.ASR: 462 case TacticalLines.ASR_ONEWAY: 463 case TacticalLines.ASR_TWOWAY: 464 case TacticalLines.ASR_ALT: 465 case TacticalLines.ROUTE: 466 case TacticalLines.ROUTE_ONEWAY: 467 case TacticalLines.ROUTE_ALT: 468 case TacticalLines.HCONVOY: 469 case TacticalLines.CONVOY: 470 case TacticalLines.MFP: 471 case TacticalLines.RFL: 472 case TacticalLines.NFL: 473 case TacticalLines.CFL: 474 case TacticalLines.TRIP: 475 case TacticalLines.FSCL: 476 case TacticalLines.BCL_REVD: 477 case TacticalLines.BCL: 478 case TacticalLines.ICL: 479 case TacticalLines.IFF_OFF: 480 case TacticalLines.IFF_ON: 481 case TacticalLines.GENERIC_LINE: 482 case TacticalLines.FPF: 483 case TacticalLines.LINTGT: 484 case TacticalLines.LINTGTS: 485 case TacticalLines.MSDZ: 486 case TacticalLines.GAP: 487 case TacticalLines.IL: 488 case TacticalLines.DIRATKAIR: 489 case TacticalLines.PDF: 490 case TacticalLines.AC: 491 case TacticalLines.SAAFR: 492 case TacticalLines.LLTR: 493 case TacticalLines.SC: 494 case TacticalLines.MRR: 495 case TacticalLines.SL: 496 case TacticalLines.TC: 497 case TacticalLines.BOUNDARY: 498 case TacticalLines.WDRAWUP: 499 case TacticalLines.WITHDRAW: 500 case TacticalLines.DISENGAGE: 501 case TacticalLines.RETIRE: 502 case TacticalLines.FPOL: 503 case TacticalLines.RPOL: 504 case TacticalLines.RIP: 505 case TacticalLines.MOBILE_DEFENSE: 506 case TacticalLines.DEMONSTRATE: 507 case TacticalLines.DELAY: 508 case TacticalLines.CATK: 509 case TacticalLines.CATKBYFIRE: 510 case TacticalLines.SCREEN: 511 case TacticalLines.COVER: 512 case TacticalLines.GUARD: 513 case TacticalLines.FLOT: 514 case TacticalLines.LC: 515 case TacticalLines.PL: 516 case TacticalLines.FEBA: 517 case TacticalLines.LL: 518 case TacticalLines.EWL: 519 case TacticalLines.FCL: 520 case TacticalLines.HOLD: 521 case TacticalLines.BRDGHD: 522 case TacticalLines.HOLD_GE: 523 case TacticalLines.BRDGHD_GE: 524 case TacticalLines.LOA: 525 case TacticalLines.LOD: 526 case TacticalLines.LDLC: 527 case TacticalLines.PLD: 528 case TacticalLines.RELEASE: 529 case TacticalLines.HOL: 530 case TacticalLines.BHL: 531 result = true; 532 break; 533 default: 534 break; 535 } 536 if(armyc2.c5isr.JavaTacticalRenderer.clsUtility.isClosedPolygon(linetype)==true) 537 result=true; 538 return result; 539 } 540 541 /** 542 * @deprecated 543 */ 544 protected static void FilterPoints(TGLight tg) 545 { 546 try 547 { 548 int lineType = tg.get_LineType(); 549 double minSpikeDistance = 0; 550 switch (lineType) 551 { 552 //case TacticalLines.LC: 553 case TacticalLines.ATDITCH: 554 case TacticalLines.ATDITCHC: 555 case TacticalLines.ATDITCHM: 556 case TacticalLines.FLOT: 557 case TacticalLines.FORT_REVD: 558 case TacticalLines.FORT: 559 case TacticalLines.FORTL: 560 case TacticalLines.STRONG: 561 minSpikeDistance=25; 562 break; 563 case TacticalLines.LC: 564 case TacticalLines.OBSAREA: 565 case TacticalLines.OBSFAREA: 566 case TacticalLines.ENCIRCLE: 567 case TacticalLines.ZONE: 568 case TacticalLines.LINE: 569 case TacticalLines.ATWALL: 570 case TacticalLines.UNSP: 571 case TacticalLines.SFENCE: 572 case TacticalLines.DFENCE: 573 case TacticalLines.DOUBLEA: 574 case TacticalLines.LWFENCE: 575 case TacticalLines.HWFENCE: 576 case TacticalLines.SINGLEC: 577 case TacticalLines.DOUBLEC: 578 case TacticalLines.TRIPLE: 579 minSpikeDistance=35; 580 break; 581 case TacticalLines.UCF: 582 case TacticalLines.CF: 583 case TacticalLines.CFG: 584 case TacticalLines.CFY: 585 minSpikeDistance=60; 586 break; 587 case TacticalLines.SF: 588 case TacticalLines.USF: 589 case TacticalLines.OCCLUDED: 590 case TacticalLines.UOF: 591 minSpikeDistance=60;//was 120 592 break; 593 case TacticalLines.SFG: 594 case TacticalLines.SFY: 595 minSpikeDistance=60;//was 180 596 break; 597 case TacticalLines.WFY: 598 case TacticalLines.WFG: 599 case TacticalLines.OFY: 600 minSpikeDistance=60;//was 120 601 break; 602 case TacticalLines.WF: 603 case TacticalLines.UWF: 604 minSpikeDistance=40; 605 break; 606 607 case TacticalLines.RIDGE: 608 case TacticalLines.ICE_EDGE_RADAR: //METOCs 609 case TacticalLines.ICE_OPENINGS_FROZEN: 610 case TacticalLines.CRACKS_SPECIFIC_LOCATION: 611 minSpikeDistance=35; 612 break; 613 default: 614 return; 615 } 616 int j=0; 617 double dist=0; 618 ArrayList<POINT2>pts=new ArrayList(); 619 ArrayList<POINT2>ptsGeo=new ArrayList(); 620 pts.add(tg.Pixels.get(0)); 621 ptsGeo.add(tg.LatLongs.get(0)); 622 POINT2 lastGoodPt=tg.Pixels.get(0); 623 POINT2 currentPt=null; 624 POINT2 currentPtGeo=null; 625 boolean foundGoodPt=false; 626 int n=tg.Pixels.size(); 627 //for(j=1;j<tg.Pixels.size();j++) 628 for(j=1;j<n;j++) 629 { 630 //we can not filter out the original end points 631 currentPt=tg.Pixels.get(j); 632 currentPtGeo=tg.LatLongs.get(j); 633 if(currentPt.style==-1) 634 { 635 lastGoodPt=currentPt; 636 pts.add(currentPt); 637 ptsGeo.add(currentPtGeo); 638 foundGoodPt=true; 639 currentPt.style=0; 640 continue; 641 } 642 dist=lineutility.CalcDistanceDouble(lastGoodPt, currentPt); 643 switch(lineType) 644 { 645 case TacticalLines.LC: 646 if(dist>minSpikeDistance) 647 { 648 lastGoodPt=currentPt; 649 pts.add(currentPt); 650 ptsGeo.add(currentPtGeo); 651 foundGoodPt=true; 652 } 653 else 654 { //the last point is no good 655 //replace the last good point with the last point 656 if(j==tg.Pixels.size()-1) 657 { 658 pts.set(pts.size()-1, currentPt); 659 ptsGeo.set(ptsGeo.size()-1, currentPtGeo); 660 } 661 } 662 break; 663 default: 664 if(dist>minSpikeDistance || j==tg.Pixels.size()-1) 665 { 666 lastGoodPt=currentPt; 667 pts.add(currentPt); 668 ptsGeo.add(currentPtGeo); 669 foundGoodPt=true; 670 } 671 break; 672 } 673 } 674 if(foundGoodPt==true) 675 { 676 tg.Pixels=pts; 677 tg.LatLongs=ptsGeo; 678 } 679 } 680 catch(Exception exc) 681 { 682 ErrorLogger.LogException("clsUtility", "FilterPoints", 683 new RendererException("Failed inside FilterPoints", exc)); 684 685 } 686 } 687 688 public static ArrayList<POINT2> PixelsToLatLong(ArrayList<POINT2> pts, IPointConversion converter) 689 { 690 int j=0; 691 POINT2 pt=null; 692 POINT2 ptGeo=null; 693 ArrayList<POINT2> ptsGeo=new ArrayList(); 694 int n=pts.size(); 695 //for(j=0;j<pts.size();j++) 696 for(j=0;j<n;j++) 697 { 698 pt=pts.get(j); 699 ptGeo=PointPixelsToLatLong(pt,converter); 700 ptsGeo.add(ptGeo); 701 } 702 return ptsGeo; 703 } 704 705 protected static ArrayList<POINT2> LatLongToPixels(ArrayList<POINT2> pts, IPointConversion converter) 706 { 707 int j=0; 708 POINT2 pt=null; 709 POINT2 ptPixels=null; 710 ArrayList<POINT2> ptsPixels=new ArrayList(); 711 int n=pts.size(); 712 //for(j=0;j<pts.size();j++) 713 for(j=0;j<n;j++) 714 { 715 pt=pts.get(j); 716 ptPixels=PointLatLongToPixels(pt,converter); 717 ptsPixels.add(ptPixels); 718 } 719 return ptsPixels; 720 } 721 722 private static POINT2 PointLatLongToPixels(POINT2 ptLatLong,IPointConversion converter) 723 { 724 POINT2 pt2 = new POINT2(); 725 try 726 { 727 Point2D pt2d=POINT2ToPoint2D(ptLatLong); 728 pt2d=converter.GeoToPixels(pt2d); 729 pt2=Point2DToPOINT2(pt2d); 730 pt2.style=ptLatLong.style; 731 } catch (Exception e) { 732 armyc2.c5isr.JavaTacticalRenderer.clsUtility.WriteFile("Error in clsUtility.PointLatLongToPixels"); 733 } 734 return pt2; 735 } 736 737 protected static void FilterAXADPoints(TGLight tg, IPointConversion converter) { 738 try { 739 int lineType = tg.get_LineType(); 740 switch (lineType) { 741 case TacticalLines.CATK: 742 case TacticalLines.CATKBYFIRE: 743 case TacticalLines.AIRAOA: 744 case TacticalLines.AAAAA: 745 case TacticalLines.SPT: 746 case TacticalLines.FRONTAL_ATTACK: 747 case TacticalLines.TURNING_MOVEMENT: 748 case TacticalLines.MOVEMENT_TO_CONTACT: 749 case TacticalLines.MAIN: 750 break; 751 default: 752 return; 753 } 754 int j=0; 755 ArrayList<POINT2> pts = new ArrayList(); 756 ArrayList<POINT2> ptsGeo = new ArrayList(); 757 POINT2 pt0 = tg.Pixels.get(0); 758 POINT2 pt1 = tg.Pixels.get(1); 759 760 Point2D pt=new Point2D.Double(pt1.x,pt1.y); 761 Point2D pt1Geo2d=converter.PixelsToGeo(pt); 762 763 POINT2 pt1geo=new POINT2(pt1Geo2d.getX(),pt1Geo2d.getY()); 764 POINT2 ptj=null,ptjGeo=null; 765 POINT2 controlPt=tg.Pixels.get(tg.Pixels.size()-1); //the control point 766 POINT2 pt0Relative=lineutility.PointRelativeToLine(pt0, pt1, pt0, controlPt); 767 double relativeDist=lineutility.CalcDistanceDouble(pt0Relative, controlPt); 768 relativeDist += 5; 769 double pt0pt1dist=lineutility.CalcDistanceDouble(pt0, pt1); 770 boolean foundGoodPoint=false; 771 if(relativeDist>pt0pt1dist) 772 { 773 //first point is too close, begin rebuilding the arrays 774 pts.add(pt0); 775 pt=new Point2D.Double(pt0.x,pt0.y); 776 pt1Geo2d=converter.PixelsToGeo(pt); 777 778 pt1geo=new POINT2(pt1Geo2d.getX(),pt1Geo2d.getY()); 779 ptsGeo.add(pt1geo); 780 //create a good first point and add it to the array 781 pt1=lineutility.ExtendAlongLineDouble(pt0, pt1, relativeDist); 782 pts.add(pt1); 783 784 pt=new Point2D.Double(pt1.x,pt1.y); 785 pt1Geo2d=converter.PixelsToGeo(pt); 786 pt1geo=new POINT2(pt1Geo2d.getX(),pt1Geo2d.getY()); 787 ptsGeo.add(pt1geo); 788 } 789 else 790 { 791 //the first point is good, there is no need to do anything 792 foundGoodPoint=true; 793 pts=tg.Pixels; 794 ptsGeo=tg.LatLongs; 795 } 796 797 //do not add mores points to the array until we find at least one good point 798 int n=tg.Pixels.size(); 799 if(foundGoodPoint==false) 800 { 801 //for(j=2;j<tg.Pixels.size()-1;j++) 802 for(j=2;j<n-1;j++) 803 { 804 ptj=tg.Pixels.get(j); 805 ptjGeo=tg.LatLongs.get(j); 806 if(foundGoodPoint) 807 { 808 //then stuff the remainder of the arrays with the original points 809 pts.add(ptj); 810 ptsGeo.add(ptjGeo); 811 } 812 else //no good points yet 813 { 814 //calculate the distance and continue if it is no good 815 pt0pt1dist=lineutility.CalcDistanceDouble(pt0, ptj); 816 if(relativeDist>pt0pt1dist) 817 continue; 818 else 819 { 820 //found a good point 821 pts.add(ptj); 822 ptsGeo.add(ptjGeo); 823 //set the boolean so that it will stuff the array with the rest of the points 824 foundGoodPoint=true; 825 } 826 } 827 } 828 //finally add the control point to the arrays and set the arrays 829 pts.add(controlPt); 830 //pt1Geo2d=converter.convertPixelsToLonLat(controlPt.x, controlPt.y); 831 pt=new Point2D.Double(controlPt.x, controlPt.y); 832 pt1Geo2d=converter.PixelsToGeo(pt); 833 834 pt1geo=new POINT2(pt1Geo2d.getX(),pt1Geo2d.getY()); 835 ptsGeo.add(pt1geo); 836 } //end if foundGoodPoint is false 837 838 //add all the successive points which are far enough apart 839 POINT2 lastGoodPt=pts.get(1); 840 POINT2 currentPt=null; 841 POINT2 currentPtGeo=null; 842 double dist=0; 843 tg.Pixels=new ArrayList(); 844 tg.LatLongs=new ArrayList(); 845 for(j=0;j<2;j++) 846 { 847 tg.Pixels.add(pts.get(j)); 848 tg.LatLongs.add(ptsGeo.get(j)); 849 } 850 n=pts.size(); 851 //for(j=2;j<pts.size()-1;j++) 852 for(j=2;j<n-1;j++) 853 { 854 currentPt=pts.get(j); 855 currentPtGeo=ptsGeo.get(j); 856 dist=lineutility.CalcDistanceDouble(currentPt, lastGoodPt); 857 if(dist>5) 858 { 859 lastGoodPt=currentPt; 860 tg.Pixels.add(currentPt); 861 tg.LatLongs.add(currentPtGeo); 862 } 863 } 864 //add the control point 865 tg.Pixels.add(pts.get(pts.size()-1)); 866 tg.LatLongs.add(ptsGeo.get(ptsGeo.size()-1)); 867 } 868 catch (Exception exc) { 869 ErrorLogger.LogException("clsUtility", "FilterAXADPoints", 870 new RendererException("Failed inside FilterAXADPoints", exc)); 871 872 } 873 } 874 /** 875 * 876 * @param tg 877 */ 878 protected static void RemoveDuplicatePoints(TGLight tg) 879 { 880 try 881 { 882 //do not remove autoshape duplicate points 883// if(isAutoshape(tg)) 884// return; 885 switch (tg.get_LineType()) { 886 case TacticalLines.SC: 887 case TacticalLines.MRR: 888 case TacticalLines.SL: 889 case TacticalLines.TC: 890 case TacticalLines.LLTR: 891 case TacticalLines.AC: 892 case TacticalLines.SAAFR: 893 break; 894 default: 895 if(isAutoshape(tg)) 896 return; 897 } 898 899 //we assume tg.H to have colors if it is comma delimited. 900 //only exit if colors are not set 901 switch(tg.get_LineType()) //preserve segment data 902 { 903 case TacticalLines.CATK: 904 case TacticalLines.AIRAOA: 905 case TacticalLines.AAAAA: 906 case TacticalLines.SPT: 907 case TacticalLines.FRONTAL_ATTACK: 908 case TacticalLines.TURNING_MOVEMENT: 909 case TacticalLines.MOVEMENT_TO_CONTACT: 910 case TacticalLines.MAIN: 911 case TacticalLines.CATKBYFIRE: //80 912 return; 913 case TacticalLines.BOUNDARY: 914 case TacticalLines.MSR: 915 case TacticalLines.ASR: 916 case TacticalLines.ROUTE: 917 String strH=tg.get_H(); 918 if(strH != null && !strH.isEmpty()) 919 { 920 String[] strs=strH.split(","); 921 if(strs.length>1) 922 return; 923 } 924 break; 925 default: 926 break; 927 } 928 int linetype=tg.get_LineType(); 929 if(armyc2.c5isr.JavaTacticalRenderer.clsUtility.IsChange1Area(linetype)) 930 return; 931 932 POINT2 ptCurrent=null; 933 POINT2 ptLast=null; 934 Boolean isClosedPolygon= armyc2.c5isr.JavaTacticalRenderer.clsUtility.isClosedPolygon(tg.get_LineType()); 935 int minSize=2; 936 if(isClosedPolygon) 937 minSize=3; 938 for(int j=1;j<tg.Pixels.size();j++) 939 { 940 ptLast=new POINT2(tg.Pixels.get(j-1)); 941 ptCurrent=new POINT2(tg.Pixels.get(j)); 942 //if(ptCurrent.x==ptLast.x && ptCurrent.y==ptLast.y) 943 if (Math.abs(ptCurrent.x - ptLast.x)<0.5 && Math.abs(ptCurrent.y - ptLast.y)<0.5) 944 { 945 if(tg.Pixels.size()>minSize) 946 { 947 tg.Pixels.remove(j); 948 tg.LatLongs.remove(j); 949 j=1; 950 } 951 } 952 } 953 } 954 catch(Exception exc) 955 { 956 ErrorLogger.LogException("clsUtility", "RemoveDuplicatePoints", 957 new RendererException("Failed inside RemoveDuplicatePoints", exc)); 958 959 } 960 } 961 protected static POINT2 PointPixelsToLatLong(POINT2 ptPixels,IPointConversion converter) 962 { 963 POINT2 pt2 = new POINT2(); 964 try 965 { 966 //Point pt=POINT2ToPoint(ptPixels); 967 Point2D pt=new Point2D.Double(ptPixels.x,ptPixels.y); 968 Point2D pt2d=converter.PixelsToGeo(pt); 969 pt2=Point2DToPOINT2(pt2d); 970 pt2.style=ptPixels.style; 971 972 } 973 catch(Exception exc) 974 { 975 ErrorLogger.LogException("clsUtility" ,"PointPixelsToLatLong", 976 new RendererException("Could not convert point to geo", exc)); 977 } 978 return pt2; 979 } 980 981 protected static Rectangle2D getMBR(ArrayList<Point2D> clipBounds) 982 { 983 Rectangle2D rect=null; 984 try 985 { 986 int j=0; 987 Point2D pt=null; 988 double xmax=clipBounds.get(0).getX(),xmin=xmax,ymax=clipBounds.get(0).getY(),ymin=ymax; 989 int n=clipBounds.size(); 990 //for(j=0;j<clipBounds.size();j++) 991 for(j=0;j<n;j++) 992 { 993 pt=clipBounds.get(j); 994 if(pt.getX()<xmin) 995 xmin=pt.getX(); 996 if(pt.getX()>xmax) 997 xmax=pt.getX(); 998 if(pt.getY()<=ymin) 999 ymin=pt.getY(); 1000 if(pt.getY()>ymax) 1001 ymax=pt.getY(); 1002 } 1003 rect=new Rectangle2D.Double(xmin, ymin, xmax-xmin, ymax-ymin); 1004 } 1005 catch (Exception exc) { 1006 ErrorLogger.LogException(_className, "AddBoundaryPointsForLines", 1007 new RendererException("Failed inside AddBoundaryPointsForLines", exc)); 1008 } 1009 return rect; 1010 } 1011 1012 static void GetMBR(ArrayList<Shape2> shapes, 1013 POINT2 ptUl, 1014 POINT2 ptUr, 1015 POINT2 ptLr, 1016 POINT2 ptLl) { 1017 try { 1018 POINT2 firstPoint = shapes.get(0).getPoints().get(0); 1019 ptUl.x = firstPoint.x; 1020 ptUl.y = firstPoint.y; 1021 ptUr.x = firstPoint.x; 1022 ptUr.y = firstPoint.y; 1023 ptLl.x = firstPoint.x; 1024 ptLl.y = firstPoint.y; 1025 ptLr.x = firstPoint.x; 1026 ptLr.y = firstPoint.y; 1027 for (Shape2 shape: shapes) { 1028 ArrayList<POINT2> points = shape.getPoints(); 1029 for (int j = 0; j < points.size(); j++) { 1030 double x = points.get(j).x; 1031 double y = points.get(j).y; 1032 if (x < ptLl.x) { 1033 ptLl.x = x; 1034 ptUl.x = x; 1035 } 1036 if (x > ptLr.x) { 1037 ptLr.x = x; 1038 ptUr.x = x; 1039 } 1040 if (y > ptLl.y) { 1041 ptLl.y = y; 1042 ptLr.y = y; 1043 } 1044 if (y < ptUl.y) { 1045 ptUl.y = y; 1046 ptUr.y = y; 1047 } 1048 } 1049 } 1050 1051 } catch (Exception exc) { 1052 ErrorLogger.LogException(_className, "GetMBR", 1053 new RendererException("Failed inside GetMBR", exc)); 1054 } 1055 } 1056}