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