001/* 002 * To change this template, choose Tools | Templates 003 * and open the template in the editor. 004 */ 005 006package armyc2.c5isr.RenderMultipoints; 007import armyc2.c5isr.JavaLineArray.arraysupport; 008import armyc2.c5isr.JavaLineArray.CELineArray; 009import armyc2.c5isr.JavaTacticalRenderer.clsChannelUtility; 010import armyc2.c5isr.JavaTacticalRenderer.Modifier2; 011import armyc2.c5isr.JavaTacticalRenderer.TGLight; 012import armyc2.c5isr.JavaTacticalRenderer.clsUtility; 013import armyc2.c5isr.JavaTacticalRenderer.P1; 014import armyc2.c5isr.JavaLineArray.ref; 015import armyc2.c5isr.JavaLineArray.POINT2; 016import armyc2.c5isr.JavaTacticalRenderer.clsMETOC; 017import java.util.ArrayList; 018import armyc2.c5isr.JavaLineArray.Shape2; 019import armyc2.c5isr.JavaLineArray.TacticalLines; 020import armyc2.c5isr.renderer.utilities.ErrorLogger; 021import armyc2.c5isr.renderer.utilities.MSInfo; 022import armyc2.c5isr.renderer.utilities.MSLookup; 023import armyc2.c5isr.renderer.utilities.RendererException; 024import armyc2.c5isr.renderer.utilities.IPointConversion; 025import armyc2.c5isr.JavaLineArray.lineutility; 026import java.util.HashMap; 027import armyc2.c5isr.renderer.utilities.Color; 028import armyc2.c5isr.graphics2d.*; 029import armyc2.c5isr.graphics2d.BasicStroke; 030import armyc2.c5isr.graphics2d.BufferedImage; 031import armyc2.c5isr.graphics2d.Graphics2D; 032import armyc2.c5isr.graphics2d.Point2D; 033import armyc2.c5isr.graphics2d.Rectangle; 034import armyc2.c5isr.graphics2d.Rectangle2D; 035import armyc2.c5isr.renderer.utilities.RendererSettings; 036 037/** 038 * Rendering helper class 039* 040 */ 041public final class clsRenderer2 { 042 private static final String _className="clsRenderer2"; 043 /** 044 * MSR and ASR use segment data for segment colors 045 * Assumes tg.H has been revised for clipping 046 * @param tg 047 * @param shapes 048 */ 049 private static void getMSRShapes(TGLight tg, 050 ArrayList<Shape2>shapes) 051 { 052 try 053 { 054 int linetype=tg.get_LineType(); 055 if(linetype != TacticalLines.MSR && linetype != TacticalLines.ASR && linetype != TacticalLines.ROUTE) 056 return; 057 058 HashMap<Integer,Color> hmap= clsUtility.getMSRSegmentColors(tg); 059 Shape2 shape=null; 060 061 BasicStroke stroke=clsUtility.getLineStroke(tg.get_LineThickness(),tg.get_LineStyle(),tg.get_lineCap(),BasicStroke.JOIN_ROUND); 062 063 int j=0,n=tg.Pixels.size(); 064 Color color=null; 065 Shape2 segShape=null; 066 shape=new Shape2(Shape2.SHAPE_TYPE_POLYLINE); 067 shape.setLineColor(tg.get_LineColor()); 068 shape.setStroke(stroke); 069 070 //if colors are not set then use one shape 071 //assumes colors may be set if string is comma delimited 072// String strH=tg.get_H(); 073// if(strH != null && !strH.isEmpty()) 074// { 075// String[] strs=strH.split(","); 076// if(strs.length<2) 077// { 078// shape.moveTo(tg.Pixels.get(0)); 079// //n=tg.Pixels.size(); 080// //for(j=1;j<tg.Pixels.size();j++) 081// for(j=1;j<n;j++) 082// { 083// shape.lineTo(tg.Pixels.get(j)); 084// } 085// shapes.add(shape); 086// return; 087// } 088// } 089 090 //if the hashmap contains the segment then use the color corresponding to the segment 091 //in the hashtable to create a one segment shape to add to the shape array. 092 //else sdd the segment to the original shape 093 Color lastColor=null; //diagnostic 094 double dist=0,dist2=0; 095 POINT2 pt0=null,pt1=null; 096 POINT2 lastPt=null; 097 //for(j=0;j<tg.Pixels.size()-1;j++) 098 for(j=0;j<n-1;j++) 099 { 100 pt0=tg.Pixels.get(j); 101 pt1=tg.Pixels.get(j+1); 102 if(hmap !=null && hmap.containsKey(j)) 103 { 104 color=(Color)hmap.get(j); 105 if(color != lastColor) 106 { 107 if(segShape != null) 108 shapes.add(segShape); 109 110 segShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE); 111 segShape.setLineColor(color); 112 segShape.set_Style(tg.get_LineStyle()); 113 segShape.setStroke(stroke); 114 } 115 segShape.moveTo(pt0); 116 segShape.lineTo(pt1); 117 lastColor=new Color(Integer.toHexString(color.toARGB())); 118 } 119 else 120 { 121 if(hmap !=null && hmap.containsKey(j+1)) 122 { 123 shape.moveTo(pt0); 124 shape.lineTo(pt1); 125 lastPt=new POINT2(pt1); 126 } 127 else if(hmap !=null && hmap.containsKey(j-1)) 128 { 129 shape.moveTo(pt0); 130 shape.lineTo(pt1); 131 lastPt=new POINT2(pt1); 132 } 133 else if(j==tg.Pixels.size()-2) 134 { 135 shape.moveTo(pt0); 136 shape.lineTo(pt1); 137 } 138 else 139 { 140 if(lastPt==null) 141 { 142 lastPt=new POINT2(pt0); 143 shape.moveTo(lastPt); 144 //shape.lineTo(lastPt); 145 } 146 dist=lineutility.CalcDistanceDouble(pt0, pt1); 147 if(dist>10) 148 { 149 //shape.moveTo(pt0); 150 shape.lineTo(pt1); 151 lastPt=new POINT2(pt1); 152 } 153 else 154 { 155 dist2=lineutility.CalcDistanceDouble(lastPt, pt1); 156 if(dist2>10) 157 { 158 //shape.moveTo(pt0); 159 shape.lineTo(pt1); 160 lastPt=new POINT2(pt1); 161 } 162 } 163 } 164 //shapes.add(shape); 165 } 166 } 167 if(segShape != null) 168 shapes.add(segShape); 169 170 shapes.add(shape); 171 } 172 catch (Exception exc) 173 { 174 ErrorLogger.LogException(_className ,"getMSRShapes", 175 new RendererException("Failed inside getMSRShapes", exc)); 176 } 177 } 178 /** 179 * 180 * @param tg 181 * @param converter client converter 182 * @param isTextFlipped 183 * @return 184 */ 185 public static ArrayList<Shape2> GetLineArray(TGLight tg, 186 IPointConversion converter, 187 boolean isTextFlipped, 188 Object clipBounds) 189 { 190 ArrayList<Shape2> shapes=new ArrayList(); 191 try 192 { 193 if(tg.Pixels==null || tg.Pixels.isEmpty()) 194 return null; 195 double x=0; 196 double y=0; 197 double width=0; 198 double height=0; 199 Rectangle2D clipBounds2=null; 200 201 Rectangle2D clipRect=null; 202 ArrayList<Point2D>clipArray=null; 203 if(clipBounds != null) 204 { 205 if(clipBounds.getClass().isAssignableFrom(Rectangle2D.Double.class)) 206 { 207 //clipRect=(Rectangle2D.Double)clipBounds; 208 clipRect=(Rectangle2D)clipBounds; 209 x=clipRect.getMinX()-50; 210 y=clipRect.getMinY()-50; 211 width=clipRect.getWidth()+100; 212 height=clipRect.getHeight()+100; 213 clipBounds2=new Rectangle2D.Double(x,y,width,height); 214 } 215 else if(clipBounds.getClass().isAssignableFrom(Rectangle.class)) 216 { 217 Rectangle rectx=(Rectangle)clipBounds; 218 clipRect=new Rectangle2D.Double(rectx.x,rectx.y,rectx.width,rectx.height); 219 x=clipRect.getMinX()-50; 220 y=clipRect.getMinY()-50; 221 width=clipRect.getWidth()+100; 222 height=clipRect.getHeight()+100; 223 clipBounds2=new Rectangle2D.Double(x,y,width,height); 224 } 225 else if(clipBounds.getClass().isAssignableFrom(ArrayList.class)) 226 { 227 clipArray=(ArrayList<Point2D>)clipBounds; 228 clipBounds2= armyc2.c5isr.RenderMultipoints.clsUtility.getMBR(clipArray); 229 } 230 } 231 232 int lineType = tg.get_LineType(); 233 // In some cases render shapes as another line type but return to input line type before adding modifiers 234 final int inputLineType = lineType; 235 236 // Render complex arrows as simple arrow when very small 237 double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0; 238 if ((lineType == TacticalLines.FOLLA || lineType == TacticalLines.FOLSP || lineType == TacticalLines.CONVOY) 239 && lineutility.CalcDistanceDouble(tg.Pixels.get(0), tg.Pixels.get(1)) <= 30 * DPIScaleFactor) { 240 lineType = TacticalLines.DIRATKSPT; 241 tg.set_LineType(lineType); 242 } 243 244 int minPoints2; 245 MSInfo msInfo = MSLookup.getInstance().getMSLInfo(tg.get_SymbolId()); 246 if (msInfo != null) { 247 minPoints2 = msInfo.getMinPointCount(); 248 } else { 249 minPoints2 = -1; 250 } 251 252 boolean bolResult = clsUtility.IsChange1Area(lineType); 253 int bolMeTOC= clsMETOC.IsWeather(tg.get_SymbolId()); 254 255 ArrayList<POINT2>pts=new ArrayList(); 256 //uncomment one line for usas1314 257 Boolean usas1314=true; 258 int j=0,n=tg.Pixels.size(); 259 if (tg.get_LineType() == TacticalLines.SINGLEC) { 260 //reverse single concertina 261 pts=(ArrayList<POINT2>)tg.Pixels.clone(); 262 //for(j=0;j<tg.Pixels.size();j++) 263 for(j=0;j<n;j++) 264 tg.Pixels.set(j, pts.get(pts.size()-j-1)); 265 } 266 267 //set CELineArray.shapes properties 268 BufferedImage bi=new BufferedImage(8,8,BufferedImage.TYPE_INT_ARGB); 269 Graphics2D g2d=bi.createGraphics(); 270 g2d.setFont(tg.get_Font()); 271 272 if(tg.Pixels.size()<minPoints2) 273 { 274 bolResult=false; 275 } 276 277 if (bolResult) 278 { 279 280 tg.Pixels.clear(); 281 bolResult = clsUtilityCPOF.Change1TacticalAreas(tg, lineType, converter, shapes); 282 } 283 else if(bolMeTOC>0) 284 { 285 if(tg.Pixels.size()<2) 286 return null; 287 288 try 289 { 290 clsMETOC.GetMeTOCShape(tg, shapes); 291 } 292 catch(Exception exc) 293 { 294 ErrorLogger.LogException(_className ,"GetLineArray", 295 new RendererException("Failed inside GetLineArray", exc)); 296 } 297 } 298 else 299 { 300 //this will help with click-drag mode 301 if(tg.Pixels.size()<2) 302 return null; 303 304 if (CELineArray.CIsChannel(lineType) == 0) 305 { 306 if(lineType==TacticalLines.ASR || lineType==TacticalLines.MSR || lineType==TacticalLines.ROUTE) 307 { 308 getMSRShapes(tg,shapes); 309 } 310 else 311 { 312 tg.Pixels=arraysupport.GetLineArray2(tg, tg.Pixels,shapes, clipBounds2, converter); 313 } 314 } 315 else //channel type 316 { 317 clsChannelUtility.DrawChannel(tg.Pixels, lineType, tg,shapes, null, clipBounds2, converter); 318 } 319 } 320 //set CELineArray.shapes properties 321 if(bolMeTOC<=0) 322 { 323 if(lineType!=TacticalLines.ASR && lineType!=TacticalLines.MSR && lineType!=TacticalLines.ROUTE) 324 clsUtility.SetShapeProperties(tg,shapes,bi); 325 } 326 327 if (lineType != inputLineType) { 328 // lineType was switched temporarily while rendering shapes 329 tg.set_LineType(inputLineType); 330 } 331 332 //at this point tg.Pixels has the points from CELineArray 333 //the following line adds modifiers for those sybmols which require 334 //the calculated points to use for the modifiers. 335 //currentlly only BLOCK and CONTAIN use tg.Pixels for computing 336 //the modifiers after the call to GetLineArray 337 //Modifier2.AddModifiers2(tg);//flipped only for 3d for change 1 symbols 338 Modifier2.AddModifiers2(tg, converter); 339 340 //boundary has shapes for line break 341 Modifier2.GetIntegralTextShapes(tg, g2d, shapes); 342 343 bi.flush(); 344 g2d.dispose(); 345 bi=null; 346 g2d=null; 347 } 348 catch (Exception exc) 349 { 350 ErrorLogger.LogException(_className ,"GetLineArray", 351 new RendererException("Failed inside GetLineArray", exc)); 352 } 353 return shapes; 354 } 355 /** 356 * Isolate and others require special handling for the fill shapes. 357 * @param tg 358 * @param shapes the existing shapes which characterize the graphic 359 */ 360 static protected void getAutoshapeFillShape(TGLight tg, ArrayList<Shape2>shapes) 361 { 362 try 363 { 364 if(shapes==null || shapes.size()==0) 365 return; 366 if(tg.Pixels==null || tg.Pixels.size()==0) 367 return; 368 if(tg.get_FillColor()==null) 369 return; 370 371 int linetype=tg.get_LineType(); 372 int j=0; 373 Shape2 shape=new Shape2(Shape2.SHAPE_TYPE_FILL); 374 shape.setFillColor(tg.get_FillColor()); 375 shape.setLineColor(null); 376 int t=shapes.size(); 377 int n=tg.Pixels.size(); 378 switch(linetype) 379 { 380 case TacticalLines.RETAIN: 381 if(shapes!=null && !shapes.isEmpty()) 382 //for(j=0;j<shapes.size();j++) 383 for(j=0;j<t;j++) 384 shapes.get(j).setFillColor(null); 385 386 shape.moveTo(tg.Pixels.get(0)); 387 for(j=1;j<26;j++) 388 shape.lineTo(tg.Pixels.get(j)); 389 390 shape.lineTo(tg.Pixels.get(0)); 391 shapes.add(0,shape); 392 break; 393 case TacticalLines.SECURE: 394 case TacticalLines.OCCUPY: 395 if(shapes!=null && !shapes.isEmpty()) 396 //for(j=0;j<shapes.size();j++) 397 for(j=0;j<t;j++) 398 shapes.get(j).setFillColor(null); 399 400 shape.moveTo(tg.Pixels.get(0)); 401 //for(j=1;j<tg.Pixels.size()-3;j++) 402 for(j=1;j<n-3;j++) 403 shape.lineTo(tg.Pixels.get(j)); 404 405 shape.lineTo(tg.Pixels.get(0)); 406 shapes.add(0,shape); 407 break; 408 case TacticalLines.CONVOY: 409 case TacticalLines.HCONVOY: 410 if(shapes!=null && !shapes.isEmpty()) 411 //for(j=0;j<shapes.size();j++) 412 for(j=0;j<t;j++) 413 shapes.get(j).setFillColor(null); 414 415 shape.moveTo(tg.Pixels.get(0)); 416 //for(j=1;j<tg.Pixels.size();j++) 417 for(j=1;j<n;j++) 418 shape.lineTo(tg.Pixels.get(j)); 419 420 shape.lineTo(tg.Pixels.get(0)); 421 shapes.add(0,shape); 422 break; 423 case TacticalLines.CORDONSEARCH: 424 case TacticalLines.CORDONKNOCK: 425 case TacticalLines.ISOLATE: 426 //set the fillcolor to null for the existing shapes 427 //we are going to create a new fill shape 428 if(shapes!=null && !shapes.isEmpty()) 429 //for(j=0;j<shapes.size();j++) 430 for(j=0;j<t;j++) 431 shapes.get(j).setFillColor(null); 432 433 shape.moveTo(tg.Pixels.get(0)); 434 for(j=26;j<47;j++) 435 shape.lineTo(tg.Pixels.get(j)); 436 437 shape.lineTo(tg.Pixels.get(23)); 438 shape.lineTo(tg.Pixels.get(24)); 439 shape.lineTo(tg.Pixels.get(25)); 440 shape.lineTo(tg.Pixels.get(0)); 441 shapes.add(0,shape); 442 break; 443 default: 444 return; 445 } 446 } 447 catch (Exception exc) 448 { 449 ErrorLogger.LogException(_className ,"getAutoshapeFillShape", 450 new RendererException("Failed inside getAutoshapeFillShape", exc)); 451 } 452 } 453}