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