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     * <a href="https://github.com/missioncommand/mil-sym-java/wiki/2525D--Renderer-Overview#3316-scale-for-3d">Scale Calculation Example</a>
252     * @param bbox The viewable area of the map.  Passed in the format of a
253     * string "lowerLeftX,lowerLeftY,upperRightX,upperRightY." Not required
254     * but can speed up rendering in some cases.
255     * example: "-50.4,23.6,-42.2,24.2"
256     * @param modifiers keyed using constants from Modifiers.
257     * Pass in comma delimited String for modifiers with multiple values like AM, AN &amp; X
258     * @param attributes keyed using constants from MilStdAttributes.
259     * @param format {@link WebRenderer#OUTPUT_FORMAT_KML}, {@link WebRenderer#OUTPUT_FORMAT_GEOJSON} or {@link WebRenderer#OUTPUT_FORMAT_GEOSVG}
260     * @return A KML, GeoJSON or SVG string representation of the graphic.
261     */
262    public static String RenderSymbol(String id, String name, String description,
263                                      String symbolCode, String controlPoints, String altitudeMode,
264                                      double scale, String bbox, Map<String,String> modifiers, Map<String,String> attributes, int format) {
265        String output = "";
266        try {         
267                
268                JavaRendererUtilities.addAltModeToModifiersString(attributes,altitudeMode);
269        
270            if (!altitudeMode.equals("clampToGround")
271                    && (format == WebRenderer.OUTPUT_FORMAT_KML || format == WebRenderer.OUTPUT_FORMAT_GEOJSON)
272                    && JavaRendererUtilities.is3dSymbol(symbolCode)
273                    && modifiers.get(Modifiers.X_ALTITUDE_DEPTH) != null
274                    && !modifiers.get(Modifiers.X_ALTITUDE_DEPTH).isEmpty()) {
275                output = RenderMilStd3dSymbol(id, name, description, symbolCode, controlPoints, altitudeMode, scale, bbox, modifiers, attributes, format);
276            }
277
278            if (output.isEmpty()) {
279                output = MultiPointHandler.RenderSymbol(id, name, description, symbolCode, controlPoints,
280                        scale, bbox, modifiers, attributes, format);
281
282                //DEBUGGING
283                if (ErrorLogger.getLevel().intValue() <= Level.FINER.intValue()) {
284                    System.out.println("");
285                    StringBuilder sb = new StringBuilder();
286                    sb.append("\nID: ").append(id).append("\n");
287                    sb.append("Name: ").append(name).append("\n");
288                    sb.append("Description: ").append(description).append("\n");
289                    sb.append("SymbolID: ").append(symbolCode).append("\n");
290                    sb.append("Scale: ").append(String.valueOf(scale)).append("\n");
291                    sb.append("BBox: ").append(bbox).append("\n");
292                    sb.append("Coords: ").append(controlPoints).append("\n");
293                    sb.append("Modifiers: ").append(modifiers).append("\n");
294                    ErrorLogger.LogMessage("WebRenderer", "RenderSymbol", sb.toString(), Level.FINER);
295                }
296                if (ErrorLogger.getLevel().intValue() <= Level.FINEST.intValue()) {
297                    String briefOutput = output.replaceAll("</Placemark>", "</Placemark>\n");
298                    briefOutput = output.replaceAll("(?s)<description[^>]*>.*?</description>", "<description></description>");
299                    ErrorLogger.LogMessage("WebRenderer", "RenderSymbol", "Output:\n" + briefOutput, Level.FINEST);
300                }
301
302            }
303
304        } catch (Exception ea) {
305            
306            output = "{\"type\":'error',error:'There was an error creating the MilStdSymbol - " + ea.toString() + "'}";
307            ErrorLogger.LogException("WebRenderer", "RenderSymbol", ea, Level.WARNING);
308        }
309        
310        return output;
311    }
312    
313
314         
315
316
317    /**
318     * Renders all multi-point symbols, creating KML, GeoJSON or SVG for the user to
319     * parse and render as they like.
320     * This function requires the bounding box to help calculate the new
321     * locations.
322     * @param id A unique identifier used to identify the symbol by Google map.
323     * The id will be the folder name that contains the graphic.
324     * @param name a string used to display to the user as the name of the 
325     * graphic being created.
326     * @param description a brief description about the graphic being made and 
327     * what it represents.
328     * @param symbolCode A 20-30 digit symbolID corresponding to one of the
329     * graphics in the MIL-STD-2525D
330     * @param controlPoints The vertices of the graphics that make up the
331     * graphic.  Passed in the format of a string, using decimal degrees
332     * separating lat and lon by a comma, separating coordinates by a space.
333     * The following format shall be used "x1,y1 [xn,yn]..."
334     * @param pixelWidth pixel dimensions of the viewable map area
335     * @param pixelHeight pixel dimensions of the viewable map area
336     * @param bbox The viewable area of the map.  Passed in the format of a
337     * string "lowerLeftX,lowerLeftY,upperRightX,upperRightY."
338     * example: "-50.4,23.6,-42.2,24.2"
339     * @param modifiers keyed using constants from Modifiers.
340     * Pass in comma delimited String for modifiers with multiple values like AM, AN &amp; X
341     * @param attributes keyed using constants from MilStdAttributes.
342     * @param format {@link WebRenderer#OUTPUT_FORMAT_KML}, {@link WebRenderer#OUTPUT_FORMAT_GEOJSON} or {@link WebRenderer#OUTPUT_FORMAT_GEOSVG}
343     * @return A KML, GeoJSON or SVG string representation of the graphic.
344     */
345    public static String RenderSymbol2D(String id, String name, String description, String symbolCode, String controlPoints,
346            int pixelWidth, int pixelHeight, String bbox, Map<String,String> modifiers, Map<String,String> attributes, int format)
347    {
348        String output = "";
349        try
350        {
351            output = MultiPointHandler.RenderSymbol2D(id, name, description, 
352                    symbolCode, controlPoints, pixelWidth, pixelHeight, bbox, 
353                    modifiers, attributes, format);
354        }
355        catch(Exception exc)
356        {
357            output = "{\"type\":'error',error:'There was an error creating the MilStdSymbol: " + symbolCode + " - " + exc.toString() + "'}";
358        }
359        return output;
360    }
361
362    /**
363     * Renders all 3d multi-point symbols, creating KML or GeoJSON that can be
364     * used to draw it on a Google map.
365     * 3D version of RenderSymbol()
366     *
367     * @param id            A unique identifier used to identify the symbol by Google map.
368     *                      The id will be the folder name that contains the graphic.
369     * @param name          a string used to display to the user as the name of the
370     *                      graphic being created.
371     * @param description   a brief description about the graphic being made and
372     *                      what it represents.
373     * @param symbolCode    A 20-30 digit symbolID corresponding to one of the
374     *                      graphics in the MIL-STD-2525D
375     * @param controlPoints The vertices of the graphics that make up the
376     *                      graphic.  Passed in the format of a string, using decimal degrees
377     *                      separating lat and lon by a comma, separating coordinates by a space.
378     *                      The following format shall be used "x1,y1[,z1] [xn,yn[,zn]]..."
379     * @param altitudeMode  Indicates whether the symbol should interpret
380     *                      altitudes as above sea level or above ground level. Options are
381     *                      "clampToGround", "relativeToGround" (from surface of earth), "absolute"
382     *                      (sea level), "relativeToSeaFloor" (from the bottom of major bodies of
383     *                      water).
384     * @param scale         A number corresponding to how many meters one meter of our
385     *                      map represents. A value "50000" would mean 1:50K which means for every
386     *                      meter of our map it represents 50000 meters of real world distance.
387     *                      <a href="https://github.com/missioncommand/mil-sym-java/wiki/2525D--Renderer-Overview#3316-scale-for-3d">Scale Calculation Example</a>
388     * @param bbox          The viewable area of the map.  Passed in the format of a
389     *                      string "lowerLeftX,lowerLeftY,upperRightX,upperRightY." Not required
390     *                      but can speed up rendering in some cases.
391     *                      example: "-50.4,23.6,-42.2,24.2"
392     * @param modifiers     keyed using constants from Modifiers.
393     *                      Pass in comma delimited String for modifiers with multiple values like AM, AN &amp; X
394     * @param attributes    keyed using constants from MilStdAttributes.
395     * @param format        {@link WebRenderer#OUTPUT_FORMAT_KML}, {@link WebRenderer#OUTPUT_FORMAT_GEOJSON} or {@link WebRenderer#OUTPUT_FORMAT_GEOSVG}
396     * @return A KML, GeoJSON or SVG string representation of the graphic.
397     */
398    public static String RenderMilStd3dSymbol(String id, String name, String description,
399                                              String symbolCode, String controlPoints, String altitudeMode,
400                                              double scale, String bbox, Map<String, String> modifiers, Map<String, String> attributes, int format) {
401        String output = "";
402        try {
403
404            output = Shape3DHandler.RenderMilStd3dSymbol(id, name, description, symbolCode, controlPoints, altitudeMode,
405                    scale, bbox, modifiers, attributes, format);
406
407            //DEBUGGING
408            if (ErrorLogger.getLevel().intValue() <= Level.FINER.intValue()) {
409                System.out.println("");
410                StringBuilder sb = new StringBuilder();
411                sb.append("\nID: ").append(id).append("\n");
412                sb.append("Name: ").append(name).append("\n");
413                sb.append("Description: ").append(description).append("\n");
414                sb.append("SymbolID: ").append(symbolCode).append("\n");
415                sb.append("Scale: ").append(String.valueOf(scale)).append("\n");
416                sb.append("BBox: ").append(bbox).append("\n");
417                sb.append("Coords: ").append(controlPoints).append("\n");
418                sb.append("Modifiers: ").append(modifiers).append("\n");
419                ErrorLogger.LogMessage("WebRenderer", "RenderMilStd3dSymbol", sb.toString(), Level.FINER);
420            }
421            if (ErrorLogger.getLevel().intValue() <= Level.FINEST.intValue()) {
422                String briefOutput = output.replaceAll("</Placemark>", "</Placemark>\n");
423                briefOutput = output.replaceAll("(?s)<description[^>]*>.*?</description>", "<description></description>");
424                ErrorLogger.LogMessage("WebRenderer", "RenderMilStd3dSymbol", "Output:\n" + briefOutput, Level.FINEST);
425            }
426        } catch (Exception ea) {
427            output = "{\"type\":'error',error:'There was an error creating the 3D MilStdSymbol - " + ea.toString() + "'}";
428            ErrorLogger.LogException("WebRenderer", "RenderMilStd3dSymbol", ea, Level.WARNING);
429        }
430        return output;
431    }
432
433    /**
434         * Renders all MilStd 2525 multi-point symbols, creating MilStdSymbol that contains the
435         * information needed to draw the symbol on the map.
436     * DOES NOT support RADARC, CAKE, TRACK etc...
437         * ArrayList&lt;Point2D&gt; milStdSymbol.getSymbolShapes.get(index).getPolylines()
438         * and 
439         * ShapeInfo = milStdSymbol.getModifierShapes.get(index). 
440         * 
441         * 
442         * @param id
443         *            A unique identifier used to identify the symbol by Google map.
444         *            The id will be the folder name that contains the graphic.
445         * @param name
446         *            a string used to display to the user as the name of the
447         *            graphic being created.
448         * @param description
449         *            a brief description about the graphic being made and what it
450         *            represents.
451         * @param symbolCode
452         *            A 20-30 digit symbolID corresponding to one of the graphics
453         *            in the MIL-STD-2525D
454         * @param controlPoints
455         *            The vertices of the graphics that make up the graphic. Passed
456         *            in the format of a string, using decimal degrees separating
457         *            lat and lon by a comma, separating coordinates by a space. The
458         *            following format shall be used "x1,y1[,z1] [xn,yn[,zn]]..."
459         * @param altitudeMode
460         *            ignored
461         * @param scale
462         *            A number corresponding to how many meters one meter of our map
463         *            represents. A value "50000" would mean 1:50K which means for
464         *            every meter of our map it represents 50000 meters of real
465         *            world distance.
466     *            <a href="https://github.com/missioncommand/mil-sym-java/wiki/2525D--Renderer-Overview#3316-scale-for-3d">Scale Calculation Example</a>
467         * @param bbox
468         *            The viewable area of the map. Passed in the format of a string
469         *            "lowerLeftX,lowerLeftY,upperRightX,upperRightY." Not required
470         *            but can speed up rendering in some cases. example:
471         *            "-50.4,23.6,-42.2,24.2"
472         * @param modifiers
473         *            Used like:
474         *            modifiers.put(Modifiers.T_UNIQUE_DESIGNATION_1, "T");
475         *            Or
476         *            modifiers.put(Modifiers.AM_DISTANCE, "1000,2000,3000");
477         * @param attributes
478         *                        Used like:
479         *            attributes.put(MilStdAttributes.LineWidth, "3");
480         *            Or
481         *            attributes.put(MilStdAttributes.LineColor, "#00FF00");
482     * @return MilStdSymbol
483     */
484    public static MilStdSymbol RenderMultiPointAsMilStdSymbol(String id, String name, String description, String symbolCode,
485                        String controlPoints, String altitudeMode, double scale, String bbox, Map<String,String> modifiers, Map<String,String> attributes)
486    {
487                MilStdSymbol mSymbol = null;
488                try 
489                {
490                        mSymbol = MultiPointHandler.RenderSymbolAsMilStdSymbol(id, name, description, symbolCode,
491                    controlPoints, scale, bbox, modifiers, attributes);
492
493            //Uncomment to show sector1 modifiers as fill pattern
494//            int symbolSet = SymbolID.getEntityCode(symbolCode);
495//            if(symbolSet == 270707 || symbolSet == 270800 || symbolSet == 270801 || symbolSet == 151100) //Mined Areas
496//            {
497//                int size = RendererSettings.getInstance().getDefaultPixelSize();
498//
499//                ArrayList<ShapeInfo> shapes = mSymbol.getSymbolShapes();
500//                if(shapes.size() > 0){
501//                    ShapeInfo shape = shapes.get(0);
502//                    shape.setPatternFillImage(PatternFillRendererD.MakeSymbolPatternFill(symbolCode,size));
503//                    if(shape.getPatternFillImage() != null)
504//                        shape.setShader(new BitmapShader(shape.getPatternFillImage(), Shader.TileMode.REPEAT, Shader.TileMode.REPEAT));
505//                }
506//            }
507                }
508                catch (Exception ea) 
509                {
510                        mSymbol=null;
511                        ErrorLogger.LogException("WebRenderer", "RenderMultiPointAsMilStdSymbol" + " - " + symbolCode, ea, Level.WARNING);
512                }
513                
514                //System.out.println("RenderMultiPointAsMilStdSymbol exit");
515                return mSymbol;
516    }
517
518    /**
519     * Renders basic shapes as symbols, creating MilStdSymbol that contains the
520     * information needed to draw the shape on the map.
521     * ArrayList&lt;Point2D&gt; milStdSymbol.getSymbolShapes.get(index).getPolylines()
522     * and
523     * ShapeInfo = milStdSymbol.getModifierShapes.get(index).
524     *
525     *
526     * @param id
527     *            A unique identifier used to identify the symbol by Google map.
528     *            The id will be the folder name that contains the graphic.
529     * @param name
530     *            a string used to display to the user as the name of the
531     *            graphic being created.
532     * @param description
533     *            a brief description about the graphic being made and what it
534     *            represents.
535     * @param basicShapeType
536     *            {@link armyc2.c5isr.JavaLineArray.BasicShapes}
537     * @param controlPoints
538     *            The vertices of the graphics that make up the graphic. Passed
539     *            in the format of a string, using decimal degrees separating
540     *            lat and lon by a comma, separating coordinates by a space. The
541     *            following format shall be used "x1,y1[,z1] [xn,yn[,zn]]..."
542     * @param altitudeMode
543     *            ignored
544     * @param scale
545     *            A number corresponding to how many meters one meter of our map
546     *            represents. A value "50000" would mean 1:50K which means for
547     *            every meter of our map it represents 50000 meters of real
548     *            world distance.
549     *            <a href="https://github.com/missioncommand/mil-sym-java/wiki/2525D--Renderer-Overview#3316-scale-for-3d">Scale Calculation Example</a>
550     * @param bbox
551     *            The viewable area of the map. Passed in the format of a string
552     *            "lowerLeftX,lowerLeftY,upperRightX,upperRightY." Not required
553     *            but can speed up rendering in some cases. example:
554     *            "-50.4,23.6,-42.2,24.2"
555     * @param modifiers
556     *            Used like:
557     *            modifiers.put(Modifiers.T_UNIQUE_DESIGNATION_1, "T");
558     *            Or
559     *            modifiers.put(Modifiers.AM_DISTANCE, "1000,2000,3000");
560     * @param attributes
561     *                    Used like:
562     *            attributes.put(MilStdAttributes.LineWidth, "3");
563     *            Or
564     *            attributes.put(MilStdAttributes.LineColor, "#00FF00");
565     * @return MilStdSymbol
566     */
567    public static MilStdSymbol RenderBasicShapeAsMilStdSymbol(String id, String name, String description, int basicShapeType,
568                                                              String controlPoints, String altitudeMode, double scale, String bbox, Map<String, String> modifiers, Map<String, String> attributes) {
569        MilStdSymbol mSymbol = null;
570        try {
571            if (SymbolUtilities.isBasicShape(basicShapeType))
572                mSymbol = MultiPointHandler.RenderBasicShapeAsMilStdSymbol(id, name, description, basicShapeType,
573                        controlPoints, scale, bbox, modifiers, attributes);
574        } catch (Exception ea) {
575            mSymbol = null;
576            ErrorLogger.LogException("WebRenderer", "RenderBasicShapeAsMilStdSymbol" + " - " + basicShapeType, ea, Level.WARNING);
577        }
578
579        return mSymbol;
580    }
581
582    /**
583     * Renders multipoint basic shapes, creating KML, GeoJSON or SVG that can be used to draw
584     * it on a Google map.
585     * @param id A unique identifier used to identify the symbol by Google map.
586     * The id will be the folder name that contains the graphic.
587     * @param name a string used to display to the user as the name of the
588     * graphic being created.
589     * @param description a brief description about the graphic being made and
590     * what it represents.
591     * @param basicShapeType {@link armyc2.c5isr.JavaLineArray.BasicShapes}
592     * @param controlPoints The vertices of the graphics that make up the
593     * graphic.  Passed in the format of a string, using decimal degrees
594     * separating lat and lon by a comma, separating coordinates by a space.
595     * The following format shall be used "x1,y1[,z1] [xn,yn[,zn]]..."
596     * @param altitudeMode ignored
597     * @param scale A number corresponding to how many meters one meter of our
598     * map represents. A value "50000" would mean 1:50K which means for every
599     * meter of our map it represents 50000 meters of real world distance.
600     * <a href="https://github.com/missioncommand/mil-sym-java/wiki/2525D--Renderer-Overview#3316-scale-for-3d">Scale Calculation Example</a>
601     * @param bbox The viewable area of the map.  Passed in the format of a
602     * string "lowerLeftX,lowerLeftY,upperRightX,upperRightY." Not required
603     * but can speed up rendering in some cases.
604     * example: "-50.4,23.6,-42.2,24.2"
605     * @param modifiers keyed using constants from Modifiers.
606     * Pass in comma delimited String for modifiers with multiple values like AM, AN &amp; X
607     * @param attributes keyed using constants from MilStdAttributes.
608     * @param format {@link WebRenderer#OUTPUT_FORMAT_KML}, {@link WebRenderer#OUTPUT_FORMAT_GEOJSON} or {@link WebRenderer#OUTPUT_FORMAT_GEOSVG}
609     * @return A KML, GeoJSON or SVG string representation of the graphic.
610     */
611    public static String RenderBasicShape(String id, String name, String description, int basicShapeType,
612                                          String controlPoints, String altitudeMode,
613                                          double scale, String bbox, Map<String, String> modifiers, Map<String, String> attributes, int format) {
614        String output = "";
615        try {
616            if (SymbolUtilities.isBasicShape(basicShapeType))
617                output = MultiPointHandler.RenderBasicShape(id, name, description, basicShapeType, controlPoints,
618                    scale, bbox, modifiers, attributes, format);
619        } catch (Exception ea) {
620            output = "{\"type\":'error',error:'There was an error creating the MilStdSymbol - " + ea.toString() + "'}";
621            ErrorLogger.LogException("WebRenderer", "RenderBasicShape", ea, Level.WARNING);
622        }
623        return output;
624    }
625
626    /**
627     * Renders basic 3D shapes, creating KML or GeoJSON that can be used to draw
628     * it on a Google map.
629     * @param id A unique identifier used to identify the symbol by Google map.
630     * The id will be the folder name that contains the graphic.
631     * @param name a string used to display to the user as the name of the
632     * graphic being created.
633     * @param description a brief description about the graphic being made and
634     * what it represents.
635     * @param basicShapeType {@link Basic3DShapes}
636     * @param controlPoints The vertices of the graphics that make up the
637     * graphic.  Passed in the format of a string, using decimal degrees
638     * separating lat and lon by a comma, separating coordinates by a space.
639     * The following format shall be used "x1,y1[,z1] [xn,yn[,zn]]..."
640     * @param altitudeMode Indicates whether the symbol should interpret
641     * altitudes as above sea level or above ground level. Options are
642     * "clampToGround", "relativeToGround" (from surface of earth), "absolute"
643     * (sea level), "relativeToSeaFloor" (from the bottom of major bodies of
644     * water).
645     * @param scale A number corresponding to how many meters one meter of our
646     * map represents. A value "50000" would mean 1:50K which means for every
647     * meter of our map it represents 50000 meters of real world distance.
648     * <a href="https://github.com/missioncommand/mil-sym-java/wiki/2525D--Renderer-Overview#3316-scale-for-3d">Scale Calculation Example</a>
649     * @param bbox The viewable area of the map.  Passed in the format of a
650     * string "lowerLeftX,lowerLeftY,upperRightX,upperRightY." Not required
651     * but can speed up rendering in some cases.
652     * example: "-50.4,23.6,-42.2,24.2"
653     * @param modifiers {@link Map}, keyed using constants from Modifiers.
654     * Pass in comma delimited String for modifiers with multiple values like AM, AN &amp; X
655     * @param attributes {@link Map}, keyed using constants from MilStdAttributes.
656     * @param format {@link WebRenderer#OUTPUT_FORMAT_KML}, {@link #OUTPUT_FORMAT_GEOJSON}
657     * @return A KML or GeoJSON string representation of the graphic.
658     */
659    public static String RenderBasic3DShape(String id, String name, String description, int basicShapeType,
660                                            String controlPoints, String altitudeMode,
661                                            double scale, String bbox, Map<String, String> modifiers, Map<String, String> attributes, int format) {
662        String output = "";
663        try {
664            JavaRendererUtilities.addAltModeToModifiersString(attributes, altitudeMode);
665            if (SymbolUtilities.isBasicShape(basicShapeType))
666                output = Shape3DHandler.RenderBasic3DShape(id, name, description, basicShapeType, controlPoints, altitudeMode,
667                        scale, bbox, modifiers, attributes, format);
668        } catch (Exception ea) {
669            output = "{\"type\":'error',error:'There was an error creating the 3D MilStdSymbol - " + ea.toString() + "'}";
670            ErrorLogger.LogException("WebRenderer", "RenderBasic3DShape", ea, Level.WARNING);
671        }
672        return output;
673    }
674    
675    /**
676     * Given a symbol code meant for a single point symbol, returns the
677     * anchor point at which to display that image based off the image returned
678     * from the URL of the SinglePointServer.
679     * 
680     * @param symbolID - the 20-30 digit symbolID of a single point MilStd2525
681     * symbol. 
682     * @return A pixel coordinate of the format "x,y".
683     * Returns an empty string if an error occurs.
684     * @deprecated 
685     */
686        public String getSinglePointAnchor(String symbolID) {
687        String anchorPoint = "";
688        Point2D anchor = new Point2D.Double();
689        anchorPoint = anchor.getX() + "," + anchor.getY();        
690        return anchorPoint;
691    }
692
693    /**
694     * Given a symbol code meant for a single point symbol, returns the
695     * anchor point at which to display that image based off the image returned
696     * from the URL of the SinglePointServer.
697     *
698     * @param symbolID - the 20-30 digit symbolID of a single point MilStd2525
699     * symbol.
700     * @return A pixel coordinate of the format "anchorX,anchorY,SymbolBoundsX,
701     * SymbolBoundsY,SymbolBoundsWidth,SymbolBoundsHeight,IconWidth,IconHeight".
702     * Anchor, represents the center point of the core symbol within the image.
703     * The image should be centered on this point.
704     * Symbol bounds represents the bounding rectangle of the core symbol within
705     * the image.
706     * IconWidth/Height represents the height and width of the image in its
707     * entirety.
708     * Returns an empty string if an error occurs.
709     * @deprecated
710     */
711    public static String getSinglePointInfo(String symbolID)
712    {
713        String info = "";
714        Point2D anchor = new Point2D.Double();
715        Rectangle2D symbolBounds = new Rectangle2D.Double();
716        return info;
717    }
718        
719    /**
720     * Returns true if we recommend clipping a particular symbol.
721     * Would return false for and Ambush but would return true for a Line of 
722     * Contact due to the decoration on the line.
723     * @param symbolID
724     * @return 
725     */
726    public static String ShouldClipMultipointSymbol(String symbolID)
727    {
728        if(MultiPointHandler.ShouldClipSymbol(symbolID))
729            return "true";
730        else
731            return "false";
732    }
733    
734     /**
735     * Given a symbol code meant for a single point symbol, returns the
736     * symbol as a byte array.
737     *
738     * @param symbolID - the 20-30 digit symbolID of a single point MilStd2525
739     * symbol.
740     * @return byte array.
741      * @deprecated
742     */
743    public static byte[] getSinglePointByteArray(String symbolID)
744    {
745        //return sps.getSinglePointByteArray(symbolID);
746        return null;
747    }
748}