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.SymbolID; 018import armyc2.c5isr.renderer.utilities.SymbolUtilities; 019import armyc2.c5isr.web.render.utilities.Basic3DShapes; 020import armyc2.c5isr.web.render.utilities.JavaRendererUtilities; 021 022import java.util.Map; 023import java.util.logging.Level; 024import armyc2.c5isr.web.json.utilities.JSONArray; 025import armyc2.c5isr.web.json.utilities.JSONException; 026import armyc2.c5isr.web.json.utilities.JSONObject; 027 028/** 029 * Main class for rendering multi-point graphics such as Control Measures, Atmospheric, and Oceanographic. 030 */ 031//@SuppressWarnings("unused") 032public final class WebRenderer /* extends Applet */ { 033 034 public static final int OUTPUT_FORMAT_KML = 0; 035 @Deprecated 036 public static final int OUTPUT_FORMAT_JSON = 1; 037 public static final int OUTPUT_FORMAT_GEOJSON = 2; 038 public static final int OUTPUT_FORMAT_GEOSVG = 3; 039 040 041 // Arbitrary default values of attributes 042 public static final double MIN_ALT_DEFAULT = 0.0D; 043 public static final double MAX_ALT_DEFAULT = 100.0D; 044 public static final double RADIUS1_DEFAULT = 50.0D; 045 public static final double RADIUS2_DEFAULT = 100.0D; 046 public static final double LEFT_AZIMUTH_DEFAULT = 0.0D; 047 public static final double RIGHT_AZIMUTH_DEFAULT = 90.0D; 048 049 public static final String ERR_ATTRIBUTES_NOT_FORMATTED = "{\"type\":\"error\"," 050 + "\"error\":\"The attribute paramaters are not formatted " 051 + "correctly"; 052 053 public static final String DEFAULT_ATTRIBUTES = "[{radius1:" 054 + RADIUS1_DEFAULT + ",radius2:" 055 + RADIUS2_DEFAULT + ",minalt:" 056 + MIN_ALT_DEFAULT + ",maxalt:" 057 + MAX_ALT_DEFAULT + ",rightAzimuth:" 058 + RIGHT_AZIMUTH_DEFAULT + ",leftAzimuth:" 059 + LEFT_AZIMUTH_DEFAULT + "}]"; 060 061 062 private static boolean _initSuccess = false; 063 064 065 public static synchronized void init(Context context, String cacheDir) { 066 067 try 068 { 069 if(_initSuccess == false) 070 { 071 MilStdIconRenderer.getInstance().init(context); 072 //use WebRenderer.setLoggingLevel() 073 074 //sets default value for single point symbology to have an outline. 075 //outline color will be automatically determined based on line color 076 //unless a color value is manually set. 077 078 //Set Renderer Settings///////////////////////////////////////////// 079 //RendererSettings.getInstance().setSinglePointSymbolOutlineWidth(1); 080 RendererSettings.getInstance().setTextBackgroundMethod(RendererSettings.TextBackgroundMethod_OUTLINE); 081 //RendererSettings.getInstance().setTextBackgroundMethod(RendererSettings.TextBackgroundMethod_OUTLINE_QUICK); 082 //RendererSettings.getInstance().setTextOutlineWidth(2); 083 //RendererSettings.getInstance().setLabelForegroundColor(Color.BLACK.toARGB()); 084 //RendererSettings.getInstance().setLabelBackgroundColor(new Color(255, 255, 255, 200).toARGB()); 085 RendererSettings.getInstance().setModifierFont("arial", Font.PLAIN, 12); 086 ErrorLogger.setLevel(Level.FINE); 087 _initSuccess = true; 088 } 089 090 } 091 catch(Exception exc) 092 { 093 ErrorLogger.LogException("WebRenderer", "init", exc, Level.WARNING); 094 } 095 096 097 } 098 099 100 /**\ 101 * Set minimum level at which an item can be logged. 102 * In descending order: 103 * OFF = Integer.MAX_VALUE 104 * Severe = 1000 105 * Warning = 900 106 * Info = 800 107 * Config = 700 108 * Fine = 500 109 * Finer = 400 110 * Finest = 300 111 * All = Integer.MIN_VALUE 112 * Use like WebRenderer.setLoggingLevel(Level.INFO); 113 * or 114 * Use like WebRenderer.setLoggingLevel(800); 115 * @param level java.util.logging.level 116 */ 117 public static void setLoggingLevel(Level level) 118 { 119 try 120 { 121 ErrorLogger.setLevel(level,true); 122 ErrorLogger.LogMessage("WebRenderer", "setLoggingLevel(Level)", 123 "Logging level set to: " + ErrorLogger.getLevel().getName(), 124 Level.CONFIG); 125 } 126 catch(Exception exc) 127 { 128 ErrorLogger.LogException("WebRenderer", "setLoggingLevel(Level)", exc, Level.INFO); 129 } 130 } 131 132 /**\ 133 * Set minimum level at which an item can be logged. 134 * In descending order: 135 * OFF = Integer.MAX_VALUE 136 * Severe = 1000 137 * Warning = 900 138 * Info = 800 139 * Config = 700 140 * Fine = 500 141 * Finer = 400 142 * Finest = 300 143 * All = Integer.MIN_VALUE 144 * Use like WebRenderer.setLoggingLevel(Level.INFO); 145 * or 146 * Use like WebRenderer.setLoggingLevel(800); 147 * @param level int 148 */ 149 public static void setLoggingLevel(int level) 150 { 151 try 152 { 153 if(level > 1000) 154 ErrorLogger.setLevel(Level.OFF,true); 155 else if(level > 900) 156 ErrorLogger.setLevel(Level.SEVERE,true); 157 else if(level > 800) 158 ErrorLogger.setLevel(Level.WARNING,true); 159 else if(level > 700) 160 ErrorLogger.setLevel(Level.INFO,true); 161 else if(level > 500) 162 ErrorLogger.setLevel(Level.CONFIG,true); 163 else if(level > 400) 164 ErrorLogger.setLevel(Level.FINE,true); 165 else if(level > 300) 166 ErrorLogger.setLevel(Level.FINER,true); 167 else if(level > Integer.MIN_VALUE) 168 ErrorLogger.setLevel(Level.FINEST,true); 169 else 170 ErrorLogger.setLevel(Level.ALL,true); 171 172 ErrorLogger.LogMessage("WebRenderer", "setLoggingLevel(int)", 173 "Logging level set to: " + ErrorLogger.getLevel().getName(), 174 Level.CONFIG); 175 } 176 catch(Exception exc) 177 { 178 ErrorLogger.LogException("WebRenderer", "setLoggingLevel(int)", exc, Level.INFO); 179 } 180 } 181 182 /** 183 * Single Point Tactical Graphics are rendered from font files. 184 * The font size you specify here determines how big the symbols will 185 * be rendered. This should be set once at startup. 186 * @param size 187 */ 188 public static void setTacticalGraphicPointSize(int size) 189 { 190// sps.setTacticalGraphicPointSize(size); 191 } 192 193 /** 194 * Units are rendered from font files. 195 * The font size you specify here determines how big the symbols will 196 * be rendered. This should be set once at startup. 197 * @param size 198 */ 199 public static void setUnitPointSize(int size) 200 { 201// sps.setUnitPointSize(size); 202 } 203 204 /** 205 * Modifier Text Color will by default match the line color. 206 * This will override all modifier text color. 207 * @param hexColor 208 */ 209/* public static void setModifierTextColor(String hexColor) 210 { 211 Color textColor = RendererUtilities.getColorFromHexString(hexColor); 212 if(textColor==null) 213 { 214 textColor = Color.black; 215 } 216 RendererSettings.getInstance().setLabelForegroundColor(textColor.toARGB()); 217 }*/ 218 219 220 221 222 223 /** 224 * Renders all multi-point symbols, creating KML, GeoJSON or SVG that can be used to draw 225 * it on a Google map. Multipoint symbols cannot be draw the same 226 * at different scales. For instance, graphics with arrow heads will need to 227 * redraw arrowheads when you zoom in on it. Similarly, graphics like a 228 * Forward Line of Troops drawn with half circles can improve performance if 229 * clipped when the parts of the graphic that aren't on the screen. To help 230 * readjust graphics and increase performance, this function requires the 231 * scale and bounding box to help calculate the new locations. 232 * @param id A unique identifier used to identify the symbol by Google map. 233 * The id will be the folder name that contains the graphic. 234 * @param name a string used to display to the user as the name of the 235 * graphic being created. 236 * @param description a brief description about the graphic being made and 237 * what it represents. 238 * @param symbolCode A 20-30 digit symbolID corresponding to one of the 239 * graphics in the MIL-STD-2525D 240 * @param controlPoints The vertices of the graphics that make up the 241 * graphic. Passed in the format of a string, using decimal degrees 242 * separating lat and lon by a comma, separating coordinates by a space. 243 * The following format shall be used "x1,y1[,z1] [xn,yn[,zn]]..." 244 * @param altitudeMode Indicates whether the symbol should interpret 245 * altitudes as above sea level or above ground level. Options are 246 * "clampToGround", "relativeToGround" (from surface of earth), "absolute" 247 * (sea level), "relativeToSeaFloor" (from the bottom of major bodies of 248 * water). 249 * @param scale A number corresponding to how many meters one meter of our 250 * map represents. A value "50000" would mean 1:50K which means for every 251 * meter of our map it represents 50000 meters of real world distance. 252 * <a href="https://github.com/missioncommand/mil-sym-java/wiki/2525D--Renderer-Overview#3316-scale-for-3d">Scale Calculation Example</a> 253 * @param bbox The viewable area of the map. Passed in the format of a 254 * string "lowerLeftX,lowerLeftY,upperRightX,upperRightY." Not required 255 * but can speed up rendering in some cases. 256 * example: "-50.4,23.6,-42.2,24.2" 257 * @param modifiers keyed using constants from Modifiers. 258 * Pass in comma delimited String for modifiers with multiple values like AM, AN & X 259 * @param attributes keyed using constants from MilStdAttributes. 260 * @param format {@link WebRenderer#OUTPUT_FORMAT_KML}, {@link WebRenderer#OUTPUT_FORMAT_GEOJSON} or {@link WebRenderer#OUTPUT_FORMAT_GEOSVG} 261 * @return A KML, GeoJSON or SVG string representation of the graphic. 262 */ 263 public static String RenderSymbol(String id, String name, String description, 264 String symbolCode, String controlPoints, String altitudeMode, 265 double scale, String bbox, Map<String,String> modifiers, Map<String,String> attributes, int format) { 266 String output = ""; 267 try { 268 269 //catch duplicate symbols and redirect to original symbol. 270 symbolCode = interceptAndAdjustCode(symbolCode,modifiers,attributes); 271 272 JavaRendererUtilities.addAltModeToModifiersString(attributes,altitudeMode); 273 274 if (!altitudeMode.equals("clampToGround") 275 && (format == WebRenderer.OUTPUT_FORMAT_KML || format == WebRenderer.OUTPUT_FORMAT_GEOJSON) 276 && JavaRendererUtilities.is3dSymbol(symbolCode) 277 && modifiers.get(Modifiers.X_ALTITUDE_DEPTH) != null 278 && !modifiers.get(Modifiers.X_ALTITUDE_DEPTH).isEmpty()) { 279 output = RenderMilStd3dSymbol(id, name, description, symbolCode, controlPoints, altitudeMode, scale, bbox, modifiers, attributes, format); 280 } 281 282 if (output.isEmpty()) { 283 output = MultiPointHandler.RenderSymbol(id, name, description, symbolCode, controlPoints, 284 scale, bbox, modifiers, attributes, format); 285 286 //DEBUGGING 287 if (ErrorLogger.getLevel().intValue() <= Level.FINER.intValue()) { 288 System.out.println(""); 289 StringBuilder sb = new StringBuilder(); 290 sb.append("\nID: ").append(id).append("\n"); 291 sb.append("Name: ").append(name).append("\n"); 292 sb.append("Description: ").append(description).append("\n"); 293 sb.append("SymbolID: ").append(symbolCode).append("\n"); 294 sb.append("Scale: ").append(String.valueOf(scale)).append("\n"); 295 sb.append("BBox: ").append(bbox).append("\n"); 296 sb.append("Coords: ").append(controlPoints).append("\n"); 297 sb.append("Modifiers: ").append(modifiers).append("\n"); 298 ErrorLogger.LogMessage("WebRenderer", "RenderSymbol", sb.toString(), Level.FINER); 299 } 300 if (ErrorLogger.getLevel().intValue() <= Level.FINEST.intValue()) { 301 String briefOutput = output.replaceAll("</Placemark>", "</Placemark>\n"); 302 briefOutput = output.replaceAll("(?s)<description[^>]*>.*?</description>", "<description></description>"); 303 ErrorLogger.LogMessage("WebRenderer", "RenderSymbol", "Output:\n" + briefOutput, Level.FINEST); 304 } 305 306 } 307 308 } catch (Exception ea) { 309 310 output = "{\"type\":'error',error:'There was an error creating the MilStdSymbol - " + ea.toString() + "'}"; 311 ErrorLogger.LogException("WebRenderer", "RenderSymbol", ea, Level.WARNING); 312 } 313 314 return output; 315 } 316 317 318 319 320 321 /** 322 * Renders all multi-point symbols, creating KML, GeoJSON or SVG for the user to 323 * parse and render as they like. 324 * This function requires the bounding box to help calculate the new 325 * locations. 326 * @param id A unique identifier used to identify the symbol by Google map. 327 * The id will be the folder name that contains the graphic. 328 * @param name a string used to display to the user as the name of the 329 * graphic being created. 330 * @param description a brief description about the graphic being made and 331 * what it represents. 332 * @param symbolCode A 20-30 digit symbolID corresponding to one of the 333 * graphics in the MIL-STD-2525D 334 * @param controlPoints The vertices of the graphics that make up the 335 * graphic. Passed in the format of a string, using decimal degrees 336 * separating lat and lon by a comma, separating coordinates by a space. 337 * The following format shall be used "x1,y1 [xn,yn]..." 338 * @param pixelWidth pixel dimensions of the viewable map area 339 * @param pixelHeight pixel dimensions of the viewable map area 340 * @param bbox The viewable area of the map. Passed in the format of a 341 * string "lowerLeftX,lowerLeftY,upperRightX,upperRightY." 342 * example: "-50.4,23.6,-42.2,24.2" 343 * @param modifiers keyed using constants from Modifiers. 344 * Pass in comma delimited String for modifiers with multiple values like AM, AN & X 345 * @param attributes keyed using constants from MilStdAttributes. 346 * @param format {@link WebRenderer#OUTPUT_FORMAT_KML}, {@link WebRenderer#OUTPUT_FORMAT_GEOJSON} or {@link WebRenderer#OUTPUT_FORMAT_GEOSVG} 347 * @return A KML, GeoJSON or SVG string representation of the graphic. 348 */ 349 public static String RenderSymbol2D(String id, String name, String description, String symbolCode, String controlPoints, 350 int pixelWidth, int pixelHeight, String bbox, Map<String,String> modifiers, Map<String,String> attributes, int format) 351 { 352 String output = ""; 353 try 354 { 355 //catch duplicate symbols and redirect to original symbol. 356 symbolCode = interceptAndAdjustCode(symbolCode,modifiers,attributes); 357 358 output = MultiPointHandler.RenderSymbol2D(id, name, description, 359 symbolCode, controlPoints, pixelWidth, pixelHeight, bbox, 360 modifiers, attributes, format); 361 } 362 catch(Exception exc) 363 { 364 output = "{\"type\":'error',error:'There was an error creating the MilStdSymbol: " + symbolCode + " - " + exc.toString() + "'}"; 365 } 366 return output; 367 } 368 369 /** 370 * Renders all 3d multi-point symbols, creating KML or GeoJSON that can be 371 * used to draw it on a Google map. 372 * 3D version of RenderSymbol() 373 * 374 * @param id A unique identifier used to identify the symbol by Google map. 375 * The id will be the folder name that contains the graphic. 376 * @param name a string used to display to the user as the name of the 377 * graphic being created. 378 * @param description a brief description about the graphic being made and 379 * what it represents. 380 * @param symbolCode A 20-30 digit symbolID corresponding to one of the 381 * graphics in the MIL-STD-2525D 382 * @param controlPoints The vertices of the graphics that make up the 383 * graphic. Passed in the format of a string, using decimal degrees 384 * separating lat and lon by a comma, separating coordinates by a space. 385 * The following format shall be used "x1,y1[,z1] [xn,yn[,zn]]..." 386 * @param altitudeMode Indicates whether the symbol should interpret 387 * altitudes as above sea level or above ground level. Options are 388 * "clampToGround", "relativeToGround" (from surface of earth), "absolute" 389 * (sea level), "relativeToSeaFloor" (from the bottom of major bodies of 390 * water). 391 * @param scale A number corresponding to how many meters one meter of our 392 * map represents. A value "50000" would mean 1:50K which means for every 393 * meter of our map it represents 50000 meters of real world distance. 394 * <a href="https://github.com/missioncommand/mil-sym-java/wiki/2525D--Renderer-Overview#3316-scale-for-3d">Scale Calculation Example</a> 395 * @param bbox The viewable area of the map. Passed in the format of a 396 * string "lowerLeftX,lowerLeftY,upperRightX,upperRightY." Not required 397 * but can speed up rendering in some cases. 398 * example: "-50.4,23.6,-42.2,24.2" 399 * @param modifiers keyed using constants from Modifiers. 400 * Pass in comma delimited String for modifiers with multiple values like AM, AN & X 401 * @param attributes keyed using constants from MilStdAttributes. 402 * @param format {@link WebRenderer#OUTPUT_FORMAT_KML}, {@link WebRenderer#OUTPUT_FORMAT_GEOJSON} or {@link WebRenderer#OUTPUT_FORMAT_GEOSVG} 403 * @return A KML, GeoJSON or SVG string representation of the graphic. 404 */ 405 public static String RenderMilStd3dSymbol(String id, String name, String description, 406 String symbolCode, String controlPoints, String altitudeMode, 407 double scale, String bbox, Map<String, String> modifiers, Map<String, String> attributes, int format) { 408 String output = ""; 409 try { 410 411 output = Shape3DHandler.RenderMilStd3dSymbol(id, name, description, symbolCode, controlPoints, altitudeMode, 412 scale, bbox, modifiers, attributes, format); 413 414 //DEBUGGING 415 if (ErrorLogger.getLevel().intValue() <= Level.FINER.intValue()) { 416 System.out.println(""); 417 StringBuilder sb = new StringBuilder(); 418 sb.append("\nID: ").append(id).append("\n"); 419 sb.append("Name: ").append(name).append("\n"); 420 sb.append("Description: ").append(description).append("\n"); 421 sb.append("SymbolID: ").append(symbolCode).append("\n"); 422 sb.append("Scale: ").append(String.valueOf(scale)).append("\n"); 423 sb.append("BBox: ").append(bbox).append("\n"); 424 sb.append("Coords: ").append(controlPoints).append("\n"); 425 sb.append("Modifiers: ").append(modifiers).append("\n"); 426 ErrorLogger.LogMessage("WebRenderer", "RenderMilStd3dSymbol", sb.toString(), Level.FINER); 427 } 428 if (ErrorLogger.getLevel().intValue() <= Level.FINEST.intValue()) { 429 String briefOutput = output.replaceAll("</Placemark>", "</Placemark>\n"); 430 briefOutput = output.replaceAll("(?s)<description[^>]*>.*?</description>", "<description></description>"); 431 ErrorLogger.LogMessage("WebRenderer", "RenderMilStd3dSymbol", "Output:\n" + briefOutput, Level.FINEST); 432 } 433 } catch (Exception ea) { 434 output = "{\"type\":'error',error:'There was an error creating the 3D MilStdSymbol - " + ea.toString() + "'}"; 435 ErrorLogger.LogException("WebRenderer", "RenderMilStd3dSymbol", ea, Level.WARNING); 436 } 437 return output; 438 } 439 440 /** 441 * Renders all MilStd 2525 multi-point symbols, creating MilStdSymbol that contains the 442 * information needed to draw the symbol on the map. 443 * DOES NOT support RADARC, CAKE, TRACK etc... 444 * ArrayList<Point2D> milStdSymbol.getSymbolShapes.get(index).getPolylines() 445 * and 446 * ShapeInfo = milStdSymbol.getModifierShapes.get(index). 447 * 448 * 449 * @param id 450 * A unique identifier used to identify the symbol by Google map. 451 * The id will be the folder name that contains the graphic. 452 * @param name 453 * a string used to display to the user as the name of the 454 * graphic being created. 455 * @param description 456 * a brief description about the graphic being made and what it 457 * represents. 458 * @param symbolCode 459 * A 20-30 digit symbolID corresponding to one of the graphics 460 * in the MIL-STD-2525D 461 * @param controlPoints 462 * The vertices of the graphics that make up the graphic. Passed 463 * in the format of a string, using decimal degrees separating 464 * lat and lon by a comma, separating coordinates by a space. The 465 * following format shall be used "x1,y1[,z1] [xn,yn[,zn]]..." 466 * @param altitudeMode 467 * ignored 468 * @param scale 469 * A number corresponding to how many meters one meter of our map 470 * represents. A value "50000" would mean 1:50K which means for 471 * every meter of our map it represents 50000 meters of real 472 * world distance. 473 * <a href="https://github.com/missioncommand/mil-sym-java/wiki/2525D--Renderer-Overview#3316-scale-for-3d">Scale Calculation Example</a> 474 * @param bbox 475 * The viewable area of the map. Passed in the format of a string 476 * "lowerLeftX,lowerLeftY,upperRightX,upperRightY." Not required 477 * but can speed up rendering in some cases. example: 478 * "-50.4,23.6,-42.2,24.2" 479 * @param modifiers 480 * Used like: 481 * modifiers.put(Modifiers.T_UNIQUE_DESIGNATION_1, "T"); 482 * Or 483 * modifiers.put(Modifiers.AM_DISTANCE, "1000,2000,3000"); 484 * @param attributes 485 * Used like: 486 * attributes.put(MilStdAttributes.LineWidth, "3"); 487 * Or 488 * attributes.put(MilStdAttributes.LineColor, "#00FF00"); 489 * @return MilStdSymbol 490 */ 491 public static MilStdSymbol RenderMultiPointAsMilStdSymbol(String id, String name, String description, String symbolCode, 492 String controlPoints, String altitudeMode, double scale, String bbox, Map<String,String> modifiers, Map<String,String> attributes) 493 { 494 MilStdSymbol mSymbol = null; 495 try 496 { 497 //catch duplicate symbols and redirect to original symbol. 498 symbolCode = interceptAndAdjustCode(symbolCode,modifiers,attributes); 499 500 mSymbol = MultiPointHandler.RenderSymbolAsMilStdSymbol(id, name, description, symbolCode, 501 controlPoints, scale, bbox, modifiers, attributes); 502 503 //Uncomment to show sector1 modifiers as fill pattern 504// int symbolSet = SymbolID.getEntityCode(symbolCode); 505// if(symbolSet == 270707 || symbolSet == 270800 || symbolSet == 270801 || symbolSet == 151100) //Mined Areas 506// { 507// int size = RendererSettings.getInstance().getDefaultPixelSize(); 508// 509// ArrayList<ShapeInfo> shapes = mSymbol.getSymbolShapes(); 510// if(shapes.size() > 0){ 511// ShapeInfo shape = shapes.get(0); 512// shape.setPatternFillImage(PatternFillRendererD.MakeSymbolPatternFill(symbolCode,size)); 513// if(shape.getPatternFillImage() != null) 514// shape.setShader(new BitmapShader(shape.getPatternFillImage(), Shader.TileMode.REPEAT, Shader.TileMode.REPEAT)); 515// } 516// } 517 } 518 catch (Exception ea) 519 { 520 mSymbol=null; 521 ErrorLogger.LogException("WebRenderer", "RenderMultiPointAsMilStdSymbol" + " - " + symbolCode, ea, Level.WARNING); 522 } 523 524 //System.out.println("RenderMultiPointAsMilStdSymbol exit"); 525 return mSymbol; 526 } 527 528 /** 529 * Renders basic shapes as symbols, creating MilStdSymbol that contains the 530 * information needed to draw the shape on the map. 531 * ArrayList<Point2D> milStdSymbol.getSymbolShapes.get(index).getPolylines() 532 * and 533 * ShapeInfo = milStdSymbol.getModifierShapes.get(index). 534 * 535 * 536 * @param id 537 * A unique identifier used to identify the symbol by Google map. 538 * The id will be the folder name that contains the graphic. 539 * @param name 540 * a string used to display to the user as the name of the 541 * graphic being created. 542 * @param description 543 * a brief description about the graphic being made and what it 544 * represents. 545 * @param basicShapeType 546 * {@link armyc2.c5isr.JavaLineArray.BasicShapes} 547 * @param controlPoints 548 * The vertices of the graphics that make up the graphic. Passed 549 * in the format of a string, using decimal degrees separating 550 * lat and lon by a comma, separating coordinates by a space. The 551 * following format shall be used "x1,y1[,z1] [xn,yn[,zn]]..." 552 * @param altitudeMode 553 * ignored 554 * @param scale 555 * A number corresponding to how many meters one meter of our map 556 * represents. A value "50000" would mean 1:50K which means for 557 * every meter of our map it represents 50000 meters of real 558 * world distance. 559 * <a href="https://github.com/missioncommand/mil-sym-java/wiki/2525D--Renderer-Overview#3316-scale-for-3d">Scale Calculation Example</a> 560 * @param bbox 561 * The viewable area of the map. Passed in the format of a string 562 * "lowerLeftX,lowerLeftY,upperRightX,upperRightY." Not required 563 * but can speed up rendering in some cases. example: 564 * "-50.4,23.6,-42.2,24.2" 565 * @param modifiers 566 * Used like: 567 * modifiers.put(Modifiers.T_UNIQUE_DESIGNATION_1, "T"); 568 * Or 569 * modifiers.put(Modifiers.AM_DISTANCE, "1000,2000,3000"); 570 * @param attributes 571 * Used like: 572 * attributes.put(MilStdAttributes.LineWidth, "3"); 573 * Or 574 * attributes.put(MilStdAttributes.LineColor, "#00FF00"); 575 * @return MilStdSymbol 576 */ 577 public static MilStdSymbol RenderBasicShapeAsMilStdSymbol(String id, String name, String description, int basicShapeType, 578 String controlPoints, String altitudeMode, double scale, String bbox, Map<String, String> modifiers, Map<String, String> attributes) { 579 MilStdSymbol mSymbol = null; 580 try { 581 if (SymbolUtilities.isBasicShape(basicShapeType)) 582 mSymbol = MultiPointHandler.RenderBasicShapeAsMilStdSymbol(id, name, description, basicShapeType, 583 controlPoints, scale, bbox, modifiers, attributes); 584 } catch (Exception ea) { 585 mSymbol = null; 586 ErrorLogger.LogException("WebRenderer", "RenderBasicShapeAsMilStdSymbol" + " - " + basicShapeType, ea, Level.WARNING); 587 } 588 589 return mSymbol; 590 } 591 592 /** 593 * Renders multipoint basic shapes, creating KML, GeoJSON or SVG that can be used to draw 594 * it on a Google map. 595 * @param id A unique identifier used to identify the symbol by Google map. 596 * The id will be the folder name that contains the graphic. 597 * @param name a string used to display to the user as the name of the 598 * graphic being created. 599 * @param description a brief description about the graphic being made and 600 * what it represents. 601 * @param basicShapeType {@link armyc2.c5isr.JavaLineArray.BasicShapes} 602 * @param controlPoints The vertices of the graphics that make up the 603 * graphic. Passed in the format of a string, using decimal degrees 604 * separating lat and lon by a comma, separating coordinates by a space. 605 * The following format shall be used "x1,y1[,z1] [xn,yn[,zn]]..." 606 * @param altitudeMode ignored 607 * @param scale A number corresponding to how many meters one meter of our 608 * map represents. A value "50000" would mean 1:50K which means for every 609 * meter of our map it represents 50000 meters of real world distance. 610 * <a href="https://github.com/missioncommand/mil-sym-java/wiki/2525D--Renderer-Overview#3316-scale-for-3d">Scale Calculation Example</a> 611 * @param bbox The viewable area of the map. Passed in the format of a 612 * string "lowerLeftX,lowerLeftY,upperRightX,upperRightY." Not required 613 * but can speed up rendering in some cases. 614 * example: "-50.4,23.6,-42.2,24.2" 615 * @param modifiers keyed using constants from Modifiers. 616 * Pass in comma delimited String for modifiers with multiple values like AM, AN & X 617 * @param attributes keyed using constants from MilStdAttributes. 618 * @param format {@link WebRenderer#OUTPUT_FORMAT_KML}, {@link WebRenderer#OUTPUT_FORMAT_GEOJSON} or {@link WebRenderer#OUTPUT_FORMAT_GEOSVG} 619 * @return A KML, GeoJSON or SVG string representation of the graphic. 620 */ 621 public static String RenderBasicShape(String id, String name, String description, int basicShapeType, 622 String controlPoints, String altitudeMode, 623 double scale, String bbox, Map<String, String> modifiers, Map<String, String> attributes, int format) { 624 String output = ""; 625 try { 626 if (SymbolUtilities.isBasicShape(basicShapeType)) 627 output = MultiPointHandler.RenderBasicShape(id, name, description, basicShapeType, controlPoints, 628 scale, bbox, modifiers, attributes, format); 629 } catch (Exception ea) { 630 output = "{\"type\":'error',error:'There was an error creating the MilStdSymbol - " + ea.toString() + "'}"; 631 ErrorLogger.LogException("WebRenderer", "RenderBasicShape", ea, Level.WARNING); 632 } 633 return output; 634 } 635 636 /** 637 * Renders basic 3D shapes, creating KML or GeoJSON that can be used to draw 638 * it on a Google map. 639 * @param id A unique identifier used to identify the symbol by Google map. 640 * The id will be the folder name that contains the graphic. 641 * @param name a string used to display to the user as the name of the 642 * graphic being created. 643 * @param description a brief description about the graphic being made and 644 * what it represents. 645 * @param basicShapeType {@link Basic3DShapes} 646 * @param controlPoints The vertices of the graphics that make up the 647 * graphic. Passed in the format of a string, using decimal degrees 648 * separating lat and lon by a comma, separating coordinates by a space. 649 * The following format shall be used "x1,y1[,z1] [xn,yn[,zn]]..." 650 * @param altitudeMode Indicates whether the symbol should interpret 651 * altitudes as above sea level or above ground level. Options are 652 * "clampToGround", "relativeToGround" (from surface of earth), "absolute" 653 * (sea level), "relativeToSeaFloor" (from the bottom of major bodies of 654 * water). 655 * @param scale A number corresponding to how many meters one meter of our 656 * map represents. A value "50000" would mean 1:50K which means for every 657 * meter of our map it represents 50000 meters of real world distance. 658 * <a href="https://github.com/missioncommand/mil-sym-java/wiki/2525D--Renderer-Overview#3316-scale-for-3d">Scale Calculation Example</a> 659 * @param bbox The viewable area of the map. Passed in the format of a 660 * string "lowerLeftX,lowerLeftY,upperRightX,upperRightY." Not required 661 * but can speed up rendering in some cases. 662 * example: "-50.4,23.6,-42.2,24.2" 663 * @param modifiers {@link Map}, keyed using constants from Modifiers. 664 * Pass in comma delimited String for modifiers with multiple values like AM, AN & X 665 * @param attributes {@link Map}, keyed using constants from MilStdAttributes. 666 * @param format {@link WebRenderer#OUTPUT_FORMAT_KML}, {@link #OUTPUT_FORMAT_GEOJSON} 667 * @return A KML or GeoJSON string representation of the graphic. 668 */ 669 public static String RenderBasic3DShape(String id, String name, String description, int basicShapeType, 670 String controlPoints, String altitudeMode, 671 double scale, String bbox, Map<String, String> modifiers, Map<String, String> attributes, int format) { 672 String output = ""; 673 try { 674 JavaRendererUtilities.addAltModeToModifiersString(attributes, altitudeMode); 675 if (SymbolUtilities.isBasicShape(basicShapeType)) 676 output = Shape3DHandler.RenderBasic3DShape(id, name, description, basicShapeType, controlPoints, altitudeMode, 677 scale, bbox, modifiers, attributes, format); 678 } catch (Exception ea) { 679 output = "{\"type\":'error',error:'There was an error creating the 3D MilStdSymbol - " + ea.toString() + "'}"; 680 ErrorLogger.LogException("WebRenderer", "RenderBasic3DShape", ea, Level.WARNING); 681 } 682 return output; 683 } 684 685 /** 686 * Given a symbol code meant for a single point symbol, returns the 687 * anchor point at which to display that image based off the image returned 688 * from the URL of the SinglePointServer. 689 * 690 * @param symbolID - the 20-30 digit symbolID of a single point MilStd2525 691 * symbol. 692 * @return A pixel coordinate of the format "x,y". 693 * Returns an empty string if an error occurs. 694 * @deprecated 695 */ 696 public String getSinglePointAnchor(String symbolID) { 697 String anchorPoint = ""; 698 Point2D anchor = new Point2D.Double(); 699 anchorPoint = anchor.getX() + "," + anchor.getY(); 700 return anchorPoint; 701 } 702 703 /** 704 * Given a symbol code meant for a single point symbol, returns the 705 * anchor point at which to display that image based off the image returned 706 * from the URL of the SinglePointServer. 707 * 708 * @param symbolID - the 20-30 digit symbolID of a single point MilStd2525 709 * symbol. 710 * @return A pixel coordinate of the format "anchorX,anchorY,SymbolBoundsX, 711 * SymbolBoundsY,SymbolBoundsWidth,SymbolBoundsHeight,IconWidth,IconHeight". 712 * Anchor, represents the center point of the core symbol within the image. 713 * The image should be centered on this point. 714 * Symbol bounds represents the bounding rectangle of the core symbol within 715 * the image. 716 * IconWidth/Height represents the height and width of the image in its 717 * entirety. 718 * Returns an empty string if an error occurs. 719 * @deprecated 720 */ 721 public static String getSinglePointInfo(String symbolID) 722 { 723 String info = ""; 724 Point2D anchor = new Point2D.Double(); 725 Rectangle2D symbolBounds = new Rectangle2D.Double(); 726 return info; 727 } 728 729 /** 730 * Returns true if we recommend clipping a particular symbol. 731 * Would return false for and Ambush but would return true for a Line of 732 * Contact due to the decoration on the line. 733 * @param symbolID 734 * @return 735 */ 736 public static String ShouldClipMultipointSymbol(String symbolID) 737 { 738 if(MultiPointHandler.ShouldClipSymbol(symbolID)) 739 return "true"; 740 else 741 return "false"; 742 } 743 744 /** 745 * Given a symbol code meant for a single point symbol, returns the 746 * symbol as a byte array. 747 * 748 * @param symbolID - the 20-30 digit symbolID of a single point MilStd2525 749 * symbol. 750 * @return byte array. 751 * @deprecated 752 */ 753 public static byte[] getSinglePointByteArray(String symbolID) 754 { 755 //return sps.getSinglePointByteArray(symbolID); 756 return null; 757 } 758 759 /** 760 * There are a handful of redundant symbols in APP6 that are duplicate symbols that could be properly rendered 761 * using the original symbol with the appropriate modifier changes. 762 * Here we intercept and adjust that values as needed. 763 * @param symbolID 764 * @param modifiers 765 * @param attributes 766 * @return 767 */ 768 private static String interceptAndAdjustCode(String symbolID, Map<String, String> modifiers, Map<String, String> attributes) 769 { 770 if(SymbolID.getSymbolSet(symbolID)==SymbolID.SymbolSet_ControlMeasure) 771 { 772 String returnVal = symbolID; 773 int etc = SymbolID.getEntityCode(symbolID); 774 switch (etc) 775 { 776 case 151406://Axis of Advance for a Feint 777 returnVal = SymbolID.setEntityCode(returnVal,151404);//SUpporting Atttack 778 returnVal = SymbolID.setHQTFD(returnVal,SymbolID.HQTFD_FeintDummy); 779 break; 780 case 140605://Direction of attack feint 781 returnVal = SymbolID.setEntityCode(returnVal,140603);//Direction of Supporting Attack 782 returnVal = SymbolID.setHQTFD(returnVal,SymbolID.HQTFD_FeintDummy); 783 break; 784 case 270705://Dummy Minefield 785 returnVal = SymbolID.setEntityCode(returnVal,270701);//Static Depiction 786 returnVal = SymbolID.setHQTFD(returnVal,SymbolID.HQTFD_FeintDummy); 787 break; 788 case 270706://Dummy Minefield, Dynamic 789 returnVal = SymbolID.setEntityCode(returnVal,270707);//Dynamic Depiction 790 returnVal = SymbolID.setHQTFD(returnVal,SymbolID.HQTFD_FeintDummy); 791 break; 792 case 270900://Decoy Mined Area 793 returnVal = SymbolID.setEntityCode(returnVal,270800);//Mined Area 794 returnVal = SymbolID.setHQTFD(returnVal,SymbolID.HQTFD_FeintDummy); 795 break; 796 case 270901://Decoy Mined Area, Fenced 797 returnVal = SymbolID.setEntityCode(returnVal,270801);//Mined Area 798 returnVal = SymbolID.setHQTFD(returnVal,SymbolID.HQTFD_FeintDummy); 799 break; 800 } 801 return returnVal; 802 } 803 else return symbolID; 804 } 805}