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