package sec.web.render.utilities; import android.util.SparseArray; import armyc2.c2sd.renderer.utilities.MilStdAttributes; import armyc2.c2sd.renderer.utilities.ModifiersTG; import armyc2.c2sd.renderer.utilities.SymbolUtilities; import armyc2.c2sd.graphics2d.*; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import java.util.HashMap; import java.util.Locale; import java.util.Map; /** * * @author stephen.pinizzotto */ @SuppressWarnings("unused") public class JavaRendererUtilities { public static final String HOSTILE_FILL_COLOR = "FFFF8080"; public static final String FRIENDLY_FILL_COLOR = "FF80E0FF"; public static final String NEUTRAL_FILL_COLOR = "FFAAFFAA"; public static final String UNKNOWN_FILL_COLOR = "FFFFFF80"; /** * Converts ARGB string format to the Google used ABGR string format. Google * reverses the blue and red positioning. * * @param rgbString A color string of the format AARRGGBB in hex value. * @return the reverse of the input string in hex. The format should now be * AABBGGRR */ public static String ARGBtoABGR(String rgbString) { if(rgbString.length()==6) { String s="FF"; rgbString=s.concat(rgbString); } String bgrString = rgbString.toUpperCase(Locale.US); if(rgbString.length() == 8) { char[] c = rgbString.toCharArray(); char temp1 = c[2]; char temp2 = c[3]; c[2] = c[6]; c[3] = c[7]; c[6] = temp1; c[7] = temp2; bgrString = new String(c); } else if(rgbString.length() == 6) { char[] c = rgbString.toCharArray(); char temp1 = c[0]; char temp2 = c[1]; c[0] = c[4]; c[1] = c[5]; c[4] = temp1; c[5] = temp2; bgrString = "FF" + new String(c); //bgrString = "FF" + bgrString; } else { System.err.println("JavaRendererUtilties.ARGBtoABGR(): " + "\"" + String.valueOf(rgbString) + "\" is not a 6 or 8 character String in the format of RRGGBB or AARRGGBB"); } return bgrString; } /** * Returns a symbolId with just the identifiable symbol Id pieces. All * variable information is returned as '*'. For example, a boundary, * "GFGPGLB----KUSX" returns "G*G*GLB---****X"; * * @param symbolCode A 15 character symbol ID. * @return The normalized SymbolCode. */ public static String normalizeSymbolCode(String symbolCode) { String newSymbolCode = symbolCode; if (symbolCode.startsWith("G") || symbolCode.startsWith("S")) { // Remove Affiliation newSymbolCode = newSymbolCode.substring(0, 1) + '*' + newSymbolCode.substring(2); // Remove planned/present field newSymbolCode = newSymbolCode.substring(0, 3) + '*' + newSymbolCode.substring(4); // Remove echelon, special code and country codes newSymbolCode = newSymbolCode.substring(0, 10) + "****" + newSymbolCode.substring(14); } // If a unit replace last character with *. if (symbolCode.startsWith("S")) { newSymbolCode = newSymbolCode.substring(0, 14) + '*'; } return newSymbolCode; } public static void addAltModeToModifiersString(SparseArray<String> attributes, String altMode) { if(altMode.equals("relativeToGround")) attributes.put(MilStdAttributes.AltitudeMode, "AGL"); else if(altMode.equals("absolute")) attributes.put(MilStdAttributes.AltitudeMode, "MSL"); } /** * * @param SymbolInfo something like * "SymbolID?LineColor=0x000000&FillColor=0xFFFFFF&size=35" */ public static Map<String, String> createParameterMapFromURL(String SymbolInfo) { Map<String, String> modifiers = new HashMap<String, String>(); String symbolID = null; String parameters = null; String key = null; String value = null; String arrParameters[] = null; String arrKeyValue[] = null; String temp = null; int questionIndex = SymbolInfo.lastIndexOf('?'); try { if (questionIndex == -1) { symbolID = java.net.URLDecoder.decode(SymbolInfo, "UTF-8"); } else { symbolID = java.net.URLDecoder.decode(SymbolInfo.substring(0, questionIndex), "UTF-8"); } } catch (Exception exc) { System.err.println("Error parsing SymbolID"); System.err.println(exc.getMessage()); } try { //build a map for the other createMilstdSymbol function to use //to build a milstd symbol. if (questionIndex > 0 && (questionIndex + 1 < SymbolInfo.length())) { parameters = SymbolInfo.substring(questionIndex + 1, SymbolInfo.length()); arrParameters = parameters.split("&"); int n = arrParameters.length; //for(int i = 0; i < arrParameters.length; i++) for (int i = 0; i < n; i++) { arrKeyValue = arrParameters[i].split("="); if (arrKeyValue.length == 2 && arrKeyValue[1] != null && arrKeyValue[1].equals("") == false) { key = arrKeyValue[0]; value = arrKeyValue[1]; temp = java.net.URLDecoder.decode(value, "UTF-8"); modifiers.put(key.toUpperCase(), temp); //System.out.println("key: " + key + " value: " + temp); } } } } catch (Exception exc) { System.err.println("Error parsing \"" + key.toUpperCase() + "\" parameter from URL"); System.err.println(exc.getMessage()); } return modifiers; } /** * Try to turn a bad code into something renderable. * * @param SymbolID * @return * @deprecated use SymbolUtilties.reconcileSymbolID() 9/5/2013 */ public static String ReconcileSymbolID(String symbolID) { StringBuilder sb = new StringBuilder(""); char codingScheme = symbolID.charAt(0); if (symbolID.length() < 15) { while (symbolID.length() < 15) { symbolID += "-"; } } if (symbolID.length() > 15) { symbolID = symbolID.substring(0, 14); } if (symbolID != null && symbolID.length() == 15) { if (codingScheme == 'S' || //warfighting codingScheme == 'I' ||//sigint codingScheme == 'O' ||//stability operation codingScheme == 'E')//emergency management { sb.append(codingScheme); if (SymbolUtilities.hasValidAffiliation(symbolID) == false) { sb.append('U'); } else { sb.append(symbolID.charAt(1)); } if (SymbolUtilities.hasValidBattleDimension(symbolID) == false) { sb.append('Z'); sb.replace(0, 1, "S"); } else { sb.append(symbolID.charAt(2)); } if (SymbolUtilities.hasValidStatus(symbolID) == false) { sb.append('P'); } else { sb.append(symbolID.charAt(3)); } sb.append("------"); sb.append(symbolID.substring(10, 15)); } else if (codingScheme == 'G')//tactical { sb.append(codingScheme); if (SymbolUtilities.hasValidAffiliation(symbolID) == false) { sb.append('U'); } else { sb.append(symbolID.charAt(1)); } sb.append('G'); if (SymbolUtilities.hasValidStatus(symbolID) == false) { sb.append('P'); } else { sb.append(symbolID.charAt(3)); } sb.append("GPP---");//return an action point sb.append(symbolID.substring(10, 15)); } else if (codingScheme == 'W')//weather {//no default weather graphic return "SUZP-----------";//unknown } else//bad codingScheme { sb.append('S'); if (SymbolUtilities.hasValidAffiliation(symbolID) == false) { sb.append('U'); } else { sb.append(symbolID.charAt(1)); } if (SymbolUtilities.hasValidBattleDimension(symbolID) == false) { sb.append('Z'); } else { sb.append(symbolID.charAt(2)); } if (SymbolUtilities.hasValidStatus(symbolID) == false) { sb.append('P'); } else { sb.append(symbolID.charAt(3)); } sb.append("------"); sb.append(symbolID.substring(10, 15)); } } else { return "SUZP-----------";//unknown } return sb.toString(); } /** * Checks symbolID and if the relevant modifiers are present * * @param symbolCode * @param modifiers * @return */ public static boolean is3dSymbol(String symbolCode, SparseArray<String> modifiers) { boolean returnValue = false; try { String symbolId = symbolCode.substring(4, 10); if (symbolId.equals("ACAI--") || // Airspace Coordination Area Irregular symbolId.equals("ACAR--") || // Airspace Coordination Area Rectangular symbolId.equals("ACAC--") || // Airspace Coordination Area Circular symbolId.equals("AKPC--") || // Kill box circular symbolId.equals("AKPR--") || // Kill box rectangular symbolId.equals("AKPI--") || // Kill box irregular symbolId.equals("ALC---") || // Air corridor symbolId.equals("ALM---") || // symbolId.equals("ALS---") || // SAAFR symbolId.equals("ALU---") || // UAV symbolId.equals("ALL---") || // Low level transit route symbolId.equals("AAR---") || symbolId.equals("AAF---") || symbolId.equals("AAH---") || symbolId.equals("AAM---") || // MEZ symbolId.equals("AAML--") || // LOMEZ symbolId.equals("AAMH--")) { try { if (modifiers != null) { // These guys store array values. Put in appropriate data strucutre // for MilStdSymbol. if (modifiers.indexOfKey(ModifiersTG.X_ALTITUDE_DEPTH) >= 0) { String[] altitudes = modifiers.get(ModifiersTG.X_ALTITUDE_DEPTH).split(","); if (altitudes.length < 2) { returnValue = false; } else { returnValue = true; } } } } catch (Exception exc) { System.err.println(exc.getMessage()); } } } catch (Exception e) { System.err.println(e.getMessage()); } return returnValue; } /** * Determines if a String represents a valid number * * @param text * @return "1.56" == true, "1ab" == false */ public static boolean isNumber(String text) { if (text != null && text.matches("((-|\\+)?[0-9]+(\\.[0-9]+)?)+")) { return true; } else { return false; } } /** * Takes a throwable and puts it's stacktrace into a string. * * @param thrown * @return */ public static String getStackTrace(Throwable thrown) { try { Writer writer = new StringWriter(); PrintWriter printWriter = new PrintWriter(writer); thrown.printStackTrace(printWriter); return writer.toString(); } catch (Exception exc) { //System.out.println("JavaRendererUtilties.getStackTrace()"); //return "Error - couldn't retrieve stack trace"; return ""; } } public static Point2D getEndPointWithAngle(Point2D ptStart, //Point2D pt1, //Point2D pt2, double angle, double distance) { double newX = 0; double newY = 0; Point2D pt = new Point2D.Double(); try { //first get the angle psi between pt0 and pt1 double psi = 0;//Math.atan((pt1.y - pt0.y) / (pt1.x - pt0.x)); //double psi = Math.atan((ptStart.getY() - ptStart.getY()) / (ptStart.getX() - (ptStart.getX()+100))); //convert alpha to radians double alpha1 = Math.PI * angle / 180; //theta is the angle of extension from the x axis double theta = psi + alpha1; //dx is the x extension from pt2 double dx = distance * Math.cos(theta); //dy is the y extension form pt2 double dy = distance * Math.sin(theta); newX = ptStart.getX() + dx; newY = ptStart.getY() + dy; pt.setLocation(newX, newY); } catch (Exception exc) { System.out.println(exc.getMessage()); exc.printStackTrace(); } return pt; } /** * * @param latitude1 * @param longitude1 * @param latitude2 * @param longitude2 * @param unitOfMeasure meters, kilometers, miles, feet, yards, nautical, * nautical miles. * @return */ public static double measureDistance(double latitude1, double longitude1, double latitude2, double longitude2, String unitOfMeasure) { // latitude1,latitude2 = latitude, longitude1,longitude2 = longitude //Radius is 6378.1 (km), 3963.1 (mi), 3443.9 (nm double distance = -1, rad; String uom = unitOfMeasure.toLowerCase(); if (uom.equals("meters")) { rad = 6378137; } else if (uom.equals("kilometers")) { rad = 6378.137; } else if (uom.equals("miles")) { rad = 3963.1; } else if (uom.equals("feet")) { rad = 20925524.9; } else if (uom.equals("yards")) { rad = 6975174.98; } else if (uom.equals("nautical")) { rad = 3443.9; } else if (uom.equals("nautical miles")) { rad = 3443.9; } else { return -1.0; } latitude1 = latitude1 * (Math.PI / 180); latitude2 = latitude2 * (Math.PI / 180); longitude1 = longitude1 * (Math.PI / 180); longitude2 = longitude2 * (Math.PI / 180); distance = (Math.acos(Math.cos(latitude1) * Math.cos(longitude1) * Math.cos(latitude2) * Math.cos(longitude2) + Math.cos(latitude1) * Math.sin(longitude1) * Math.cos(latitude2) * Math.sin(longitude2) + Math.sin(latitude1) * Math.sin(latitude2)) * rad); return distance; } }