001package armyc2.c5isr.web.render; 002// This import is if we need to call a javascript function 003// It requires that you import the plugins.jar from the jdk folder into the project libraries 004//import netscape.javascript.JSObject; 005 006import android.content.Context; 007import armyc2.c5isr.renderer.MilStdIconRenderer; 008import armyc2.c5isr.renderer.utilities.ErrorLogger; 009import armyc2.c5isr.renderer.utilities.MilStdAttributes; 010import armyc2.c5isr.renderer.utilities.MilStdSymbol; 011import armyc2.c5isr.renderer.utilities.Modifiers; 012import armyc2.c5isr.renderer.utilities.RendererSettings; 013import armyc2.c5isr.renderer.utilities.Color; 014import armyc2.c5isr.graphics2d.Font; 015import armyc2.c5isr.graphics2d.Point2D; 016import armyc2.c5isr.graphics2d.Rectangle2D; 017import armyc2.c5isr.renderer.utilities.SymbolUtilities; 018import armyc2.c5isr.web.render.utilities.JavaRendererUtilities; 019 020import java.util.Map; 021import java.util.logging.Level; 022import armyc2.c5isr.web.json.utilities.JSONArray; 023import armyc2.c5isr.web.json.utilities.JSONException; 024import armyc2.c5isr.web.json.utilities.JSONObject; 025 026/** 027 * Main class for rendering multi-point graphics such as Control Measures, Atmospheric, and Oceanographic. 028 */ 029//@SuppressWarnings("unused") 030public final class WebRenderer /* extends Applet */ { 031 032 public static final int OUTPUT_FORMAT_KML = 0; 033 @Deprecated 034 public static final int OUTPUT_FORMAT_JSON = 1; 035 public static final int OUTPUT_FORMAT_GEOJSON = 2; 036 public static final int OUTPUT_FORMAT_GEOSVG = 3; 037 038 039 // Arbitrary default values of attributes 040 public static final double MIN_ALT_DEFAULT = 0.0D; 041 public static final double MAX_ALT_DEFAULT = 100.0D; 042 public static final double RADIUS1_DEFAULT = 50.0D; 043 public static final double RADIUS2_DEFAULT = 100.0D; 044 public static final double LEFT_AZIMUTH_DEFAULT = 0.0D; 045 public static final double RIGHT_AZIMUTH_DEFAULT = 90.0D; 046 047 public static final String ERR_ATTRIBUTES_NOT_FORMATTED = "{\"type\":\"error\"," 048 + "\"error\":\"The attribute paramaters are not formatted " 049 + "correctly"; 050 051 public static final String DEFAULT_ATTRIBUTES = "[{radius1:" 052 + RADIUS1_DEFAULT + ",radius2:" 053 + RADIUS2_DEFAULT + ",minalt:" 054 + MIN_ALT_DEFAULT + ",maxalt:" 055 + MAX_ALT_DEFAULT + ",rightAzimuth:" 056 + RIGHT_AZIMUTH_DEFAULT + ",leftAzimuth:" 057 + LEFT_AZIMUTH_DEFAULT + "}]"; 058 059 060 private static boolean _initSuccess = false; 061 062 063 public static synchronized void init(Context context, String cacheDir) { 064 065 try 066 { 067 if(_initSuccess == false) 068 { 069 MilStdIconRenderer.getInstance().init(context); 070 //use WebRenderer.setLoggingLevel() 071 072 //sets default value for single point symbology to have an outline. 073 //outline color will be automatically determined based on line color 074 //unless a color value is manually set. 075 076 //Set Renderer Settings///////////////////////////////////////////// 077 //RendererSettings.getInstance().setSinglePointSymbolOutlineWidth(1); 078 RendererSettings.getInstance().setTextBackgroundMethod(RendererSettings.TextBackgroundMethod_OUTLINE); 079 //RendererSettings.getInstance().setTextBackgroundMethod(RendererSettings.TextBackgroundMethod_OUTLINE_QUICK); 080 //RendererSettings.getInstance().setTextOutlineWidth(2); 081 //RendererSettings.getInstance().setLabelForegroundColor(Color.BLACK.toARGB()); 082 //RendererSettings.getInstance().setLabelBackgroundColor(new Color(255, 255, 255, 200).toARGB()); 083 RendererSettings.getInstance().setModifierFont("arial", Font.PLAIN, 12); 084 ErrorLogger.setLevel(Level.FINE); 085 _initSuccess = true; 086 } 087 088 } 089 catch(Exception exc) 090 { 091 ErrorLogger.LogException("WebRenderer", "init", exc, Level.WARNING); 092 } 093 094 095 } 096 097 098 /**\ 099 * Set minimum level at which an item can be logged. 100 * In descending order: 101 * OFF = Integer.MAX_VALUE 102 * Severe = 1000 103 * Warning = 900 104 * Info = 800 105 * Config = 700 106 * Fine = 500 107 * Finer = 400 108 * Finest = 300 109 * All = Integer.MIN_VALUE 110 * Use like WebRenderer.setLoggingLevel(Level.INFO); 111 * or 112 * Use like WebRenderer.setLoggingLevel(800); 113 * @param level java.util.logging.level 114 */ 115 public static void setLoggingLevel(Level level) 116 { 117 try 118 { 119 ErrorLogger.setLevel(level,true); 120 ErrorLogger.LogMessage("WebRenderer", "setLoggingLevel(Level)", 121 "Logging level set to: " + ErrorLogger.getLevel().getName(), 122 Level.CONFIG); 123 } 124 catch(Exception exc) 125 { 126 ErrorLogger.LogException("WebRenderer", "setLoggingLevel(Level)", exc, Level.INFO); 127 } 128 } 129 130 /**\ 131 * Set minimum level at which an item can be logged. 132 * In descending order: 133 * OFF = Integer.MAX_VALUE 134 * Severe = 1000 135 * Warning = 900 136 * Info = 800 137 * Config = 700 138 * Fine = 500 139 * Finer = 400 140 * Finest = 300 141 * All = Integer.MIN_VALUE 142 * Use like WebRenderer.setLoggingLevel(Level.INFO); 143 * or 144 * Use like WebRenderer.setLoggingLevel(800); 145 * @param level int 146 */ 147 public static void setLoggingLevel(int level) 148 { 149 try 150 { 151 if(level > 1000) 152 ErrorLogger.setLevel(Level.OFF,true); 153 else if(level > 900) 154 ErrorLogger.setLevel(Level.SEVERE,true); 155 else if(level > 800) 156 ErrorLogger.setLevel(Level.WARNING,true); 157 else if(level > 700) 158 ErrorLogger.setLevel(Level.INFO,true); 159 else if(level > 500) 160 ErrorLogger.setLevel(Level.CONFIG,true); 161 else if(level > 400) 162 ErrorLogger.setLevel(Level.FINE,true); 163 else if(level > 300) 164 ErrorLogger.setLevel(Level.FINER,true); 165 else if(level > Integer.MIN_VALUE) 166 ErrorLogger.setLevel(Level.FINEST,true); 167 else 168 ErrorLogger.setLevel(Level.ALL,true); 169 170 ErrorLogger.LogMessage("WebRenderer", "setLoggingLevel(int)", 171 "Logging level set to: " + ErrorLogger.getLevel().getName(), 172 Level.CONFIG); 173 } 174 catch(Exception exc) 175 { 176 ErrorLogger.LogException("WebRenderer", "setLoggingLevel(int)", exc, Level.INFO); 177 } 178 } 179 180 /** 181 * Single Point Tactical Graphics are rendered from font files. 182 * The font size you specify here determines how big the symbols will 183 * be rendered. This should be set once at startup. 184 * @param size 185 */ 186 public static void setTacticalGraphicPointSize(int size) 187 { 188// sps.setTacticalGraphicPointSize(size); 189 } 190 191 /** 192 * Units are rendered from font files. 193 * The font size you specify here determines how big the symbols will 194 * be rendered. This should be set once at startup. 195 * @param size 196 */ 197 public static void setUnitPointSize(int size) 198 { 199// sps.setUnitPointSize(size); 200 } 201 202 /** 203 * Modifier Text Color will by default match the line color. 204 * This will override all modifier text color. 205 * @param hexColor 206 */ 207/* public static void setModifierTextColor(String hexColor) 208 { 209 Color textColor = RendererUtilities.getColorFromHexString(hexColor); 210 if(textColor==null) 211 { 212 textColor = Color.black; 213 } 214 RendererSettings.getInstance().setLabelForegroundColor(textColor.toARGB()); 215 }*/ 216 217 218 219 220 221 /** 222 * Renders all multi-point symbols, creating KML that can be used to draw 223 * it on a Google map. Multipoint symbols cannot be draw the same 224 * at different scales. For instance, graphics with arrow heads will need to 225 * redraw arrowheads when you zoom in on it. Similarly, graphics like a 226 * Forward Line of Troops drawn with half circles can improve performance if 227 * clipped when the parts of the graphic that aren't on the screen. To help 228 * readjust graphics and increase performance, this function requires the 229 * scale and bounding box to help calculate the new locations. 230 * @param id A unique identifier used to identify the symbol by Google map. 231 * The id will be the folder name that contains the graphic. 232 * @param name a string used to display to the user as the name of the 233 * graphic being created. 234 * @param description a brief description about the graphic being made and 235 * what it represents. 236 * @param symbolCode A 20-30 digit symbolID corresponding to one of the 237 * graphics in the MIL-STD-2525D 238 * @param controlPoints The vertices of the graphics that make up the 239 * graphic. Passed in the format of a string, using decimal degrees 240 * separating lat and lon by a comma, separating coordinates by a space. 241 * The following format shall be used "x1,y1[,z1] [xn,yn[,zn]]..." 242 * @param altitudeMode Indicates whether the symbol should interpret 243 * altitudes as above sea level or above ground level. Options are 244 * "clampToGround", "relativeToGround" (from surface of earth), "absolute" 245 * (sea level), "relativeToSeaFloor" (from the bottom of major bodies of 246 * water). 247 * @param scale A number corresponding to how many meters one meter of our 248 * map represents. A value "50000" would mean 1:50K which means for every 249 * meter of our map it represents 50000 meters of real world distance. 250 * @param bbox The viewable area of the map. Passed in the format of a 251 * string "lowerLeftX,lowerLeftY,upperRightX,upperRightY." Not required 252 * but can speed up rendering in some cases. 253 * example: "-50.4,23.6,-42.2,24.2" 254 * @param modifiers keyed using constants from Modifiers. 255 * Pass in comma delimited String for modifiers with multiple values like AM, AN & X 256 * @param attributes keyed using constants from MilStdAttributes. 257 * @param format An enumeration: 2 for GeoJSON. 258 * @return A JSON string representation of the graphic. 259 */ 260 public static String RenderSymbol(String id, String name, String description, 261 String symbolCode, String controlPoints, String altitudeMode, 262 double scale, String bbox, Map<String,String> modifiers, Map<String,String> attributes, int format) { 263 String output = ""; 264 try { 265 266 JavaRendererUtilities.addAltModeToModifiersString(attributes,altitudeMode); 267 268 269 output = MultiPointHandler.RenderSymbol(id, name, description, symbolCode, controlPoints, 270 scale, bbox, modifiers, attributes, format); 271 272 //DEBUGGING 273 if(ErrorLogger.getLevel().intValue() <= Level.FINER.intValue()) 274 { 275 System.out.println(""); 276 StringBuilder sb = new StringBuilder(); 277 sb.append("\nID: " + id + "\n"); 278 sb.append("Name: " + name + "\n"); 279 sb.append("Description: " + description + "\n"); 280 sb.append("SymbolID: " + symbolCode + "\n"); 281 sb.append("Scale: " + String.valueOf(scale) + "\n"); 282 sb.append("BBox: " + bbox + "\n"); 283 sb.append("Coords: " + controlPoints + "\n"); 284 sb.append("Modifiers: " + modifiers + "\n"); 285 ErrorLogger.LogMessage("WebRenderer", "RenderSymbol", sb.toString(),Level.FINER); 286 } 287 if(ErrorLogger.getLevel().intValue() <= Level.FINEST.intValue()) 288 { 289 String briefOutput = output.replaceAll("</Placemark>", "</Placemark>\n"); 290 briefOutput = output.replaceAll("(?s)<description[^>]*>.*?</description>", "<description></description>"); 291 ErrorLogger.LogMessage("WebRenderer", "RenderSymbol", "Output:\n" + briefOutput,Level.FINEST); 292 } 293 294 295 296 } catch (Exception ea) { 297 298 output = "{\"type\":'error',error:'There was an error creating the MilStdSymbol - " + ea.toString() + "'}"; 299 ErrorLogger.LogException("WebRenderer", "RenderSymbol", ea, Level.WARNING); 300 } 301 302 return output; 303 } 304 305 306 307 308 309 /** 310 * Renders all multi-point symbols, creating KML or JSON for the user to 311 * parse and render as they like. 312 * This function requires the bounding box to help calculate the new 313 * locations. 314 * @param id A unique identifier used to identify the symbol by Google map. 315 * The id will be the folder name that contains the graphic. 316 * @param name a string used to display to the user as the name of the 317 * graphic being created. 318 * @param description a brief description about the graphic being made and 319 * what it represents. 320 * @param symbolCode A 20-30 digit symbolID corresponding to one of the 321 * graphics in the MIL-STD-2525D 322 * @param controlPoints The vertices of the graphics that make up the 323 * graphic. Passed in the format of a string, using decimal degrees 324 * separating lat and lon by a comma, separating coordinates by a space. 325 * The following format shall be used "x1,y1 [xn,yn]..." 326 * @param pixelWidth pixel dimensions of the viewable map area 327 * @param pixelHeight pixel dimensions of the viewable map area 328 * @param bbox The viewable area of the map. Passed in the format of a 329 * string "lowerLeftX,lowerLeftY,upperRightX,upperRightY." 330 * example: "-50.4,23.6,-42.2,24.2" 331 * @param modifiers keyed using constants from Modifiers. 332 * Pass in comma delimited String for modifiers with multiple values like AM, AN & X 333 * @param attributes keyed using constants from MilStdAttributes. 334 * @param format An enumeration: 2 for GeoJSON. 335 * @return A JSON (1) or KML (0) string representation of the graphic. 336 */ 337 public static String RenderSymbol2D(String id, String name, String description, String symbolCode, String controlPoints, 338 int pixelWidth, int pixelHeight, String bbox, Map<String,String> modifiers, Map<String,String> attributes, int format) 339 { 340 String output = ""; 341 try 342 { 343 output = MultiPointHandler.RenderSymbol2D(id, name, description, 344 symbolCode, controlPoints, pixelWidth, pixelHeight, bbox, 345 modifiers, attributes, format); 346 } 347 catch(Exception exc) 348 { 349 output = "{\"type\":'error',error:'There was an error creating the MilStdSymbol: " + symbolCode + " - " + exc.toString() + "'}"; 350 } 351 return output; 352 } 353 354 355 356 /** 357 * Renders all MilStd 2525 multi-point symbols, creating MilStdSymbol that contains the 358 * information needed to draw the symbol on the map. 359 * DOES NOT support RADARC, CAKE, TRACK etc... 360 * ArrayList<Point2D> milStdSymbol.getSymbolShapes.get(index).getPolylines() 361 * and 362 * ShapeInfo = milStdSymbol.getModifierShapes.get(index). 363 * 364 * 365 * @param id 366 * A unique identifier used to identify the symbol by Google map. 367 * The id will be the folder name that contains the graphic. 368 * @param name 369 * a string used to display to the user as the name of the 370 * graphic being created. 371 * @param description 372 * a brief description about the graphic being made and what it 373 * represents. 374 * @param symbolCode 375 * A 20-30 digit symbolID corresponding to one of the graphics 376 * in the MIL-STD-2525D 377 * @param controlPoints 378 * The vertices of the graphics that make up the graphic. Passed 379 * in the format of a string, using decimal degrees separating 380 * lat and lon by a comma, separating coordinates by a space. The 381 * following format shall be used "x1,y1[,z1] [xn,yn[,zn]]..." 382 * @param altitudeMode 383 * Indicates whether the symbol should interpret altitudes as 384 * above sea level or above ground level. Options are 385 * "clampToGround", "relativeToGround" (from surface of earth), 386 * "absolute" (sea level), "relativeToSeaFloor" (from the bottom 387 * of major bodies of water). 388 * @param scale 389 * A number corresponding to how many meters one meter of our map 390 * represents. A value "50000" would mean 1:50K which means for 391 * every meter of our map it represents 50000 meters of real 392 * world distance. 393 * @param bbox 394 * The viewable area of the map. Passed in the format of a string 395 * "lowerLeftX,lowerLeftY,upperRightX,upperRightY." Not required 396 * but can speed up rendering in some cases. example: 397 * "-50.4,23.6,-42.2,24.2" 398 * @param modifiers 399 * Used like: 400 * modifiers.put(Modifiers.T_UNIQUE_DESIGNATION_1, "T"); 401 * Or 402 * modifiers.put(Modifiers.AM_DISTANCE, "1000,2000,3000"); 403 * @param attributes 404 * Used like: 405 * attributes.put(MilStdAttributes.LineWidth, "3"); 406 * Or 407 * attributes.put(MilStdAttributes.LineColor, "#00FF00"); 408 * @return MilStdSymbol 409 */ 410 public static MilStdSymbol RenderMultiPointAsMilStdSymbol(String id, String name, String description, String symbolCode, 411 String controlPoints, String altitudeMode, double scale, String bbox, Map<String,String> modifiers, Map<String,String> attributes) 412 { 413 MilStdSymbol mSymbol = null; 414 try 415 { 416 mSymbol = MultiPointHandler.RenderSymbolAsMilStdSymbol(id, name, description, symbolCode, 417 controlPoints, scale, bbox, modifiers, attributes); 418 419 //Uncomment to show sector1 modifiers as fill pattern 420// int symbolSet = SymbolID.getEntityCode(symbolCode); 421// if(symbolSet == 270707 || symbolSet == 270800 || symbolSet == 270801 || symbolSet == 151100) //Mined Areas 422// { 423// int size = RendererSettings.getInstance().getDefaultPixelSize(); 424// 425// ArrayList<ShapeInfo> shapes = mSymbol.getSymbolShapes(); 426// if(shapes.size() > 0){ 427// ShapeInfo shape = shapes.get(0); 428// shape.setPatternFillImage(PatternFillRendererD.MakeSymbolPatternFill(symbolCode,size)); 429// if(shape.getPatternFillImage() != null) 430// shape.setShader(new BitmapShader(shape.getPatternFillImage(), Shader.TileMode.REPEAT, Shader.TileMode.REPEAT)); 431// } 432// } 433 } 434 catch (Exception ea) 435 { 436 mSymbol=null; 437 ErrorLogger.LogException("WebRenderer", "RenderMultiPointAsMilStdSymbol" + " - " + symbolCode, ea, Level.WARNING); 438 } 439 440 //System.out.println("RenderMultiPointAsMilStdSymbol exit"); 441 return mSymbol; 442 } 443 444 445 446 /** 447 * Given a symbol code meant for a single point symbol, returns the 448 * anchor point at which to display that image based off the image returned 449 * from the URL of the SinglePointServer. 450 * 451 * @param symbolID - the 20-30 digit symbolID of a single point MilStd2525 452 * symbol. 453 * @return A pixel coordinate of the format "x,y". 454 * Returns an empty string if an error occurs. 455 * @deprecated 456 */ 457 public String getSinglePointAnchor(String symbolID) { 458 String anchorPoint = ""; 459 Point2D anchor = new Point2D.Double(); 460 anchorPoint = anchor.getX() + "," + anchor.getY(); 461 return anchorPoint; 462 } 463 464 /** 465 * Given a symbol code meant for a single point symbol, returns the 466 * anchor point at which to display that image based off the image returned 467 * from the URL of the SinglePointServer. 468 * 469 * @param symbolID - the 20-30 digit symbolID of a single point MilStd2525 470 * symbol. 471 * @return A pixel coordinate of the format "anchorX,anchorY,SymbolBoundsX, 472 * SymbolBoundsY,SymbolBoundsWidth,SymbolBoundsHeight,IconWidth,IconHeight". 473 * Anchor, represents the center point of the core symbol within the image. 474 * The image should be centered on this point. 475 * Symbol bounds represents the bounding rectangle of the core symbol within 476 * the image. 477 * IconWidth/Height represents the height and width of the image in its 478 * entirety. 479 * Returns an empty string if an error occurs. 480 * @deprecated 481 */ 482 public static String getSinglePointInfo(String symbolID) 483 { 484 String info = ""; 485 Point2D anchor = new Point2D.Double(); 486 Rectangle2D symbolBounds = new Rectangle2D.Double(); 487 return info; 488 } 489 490 /** 491 * Returns true if we recommend clipping a particular symbol. 492 * Would return false for and Ambush but would return true for a Line of 493 * Contact due to the decoration on the line. 494 * @param symbolID 495 * @return 496 */ 497 public static String ShouldClipMultipointSymbol(String symbolID) 498 { 499 if(MultiPointHandler.ShouldClipSymbol(symbolID)) 500 return "true"; 501 else 502 return "false"; 503 } 504 505 /** 506 * Given a symbol code meant for a single point symbol, returns the 507 * symbol as a byte array. 508 * 509 * @param symbolID - the 20-30 digit symbolID of a single point MilStd2525 510 * symbol. 511 * @return byte array. 512 * @deprecated 513 */ 514 public static byte[] getSinglePointByteArray(String symbolID) 515 { 516 //return sps.getSinglePointByteArray(symbolID); 517 return null; 518 } 519}