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