001package armyc2.c5isr.renderer; 002 003import android.content.Context; 004import android.util.DisplayMetrics; 005import android.util.Log; 006import android.view.WindowManager; 007 008import java.util.HashMap; 009import java.util.Map; 010import java.util.concurrent.atomic.AtomicBoolean; 011import java.util.logging.Level; 012 013import armyc2.c5isr.renderer.utilities.DrawRules; 014import armyc2.c5isr.renderer.utilities.ErrorLogger; 015import armyc2.c5isr.renderer.utilities.GENCLookup; 016import armyc2.c5isr.renderer.utilities.ImageInfo; 017import armyc2.c5isr.renderer.utilities.MSInfo; 018import armyc2.c5isr.renderer.utilities.MSLookup; 019import armyc2.c5isr.renderer.utilities.MilStdAttributes; 020import armyc2.c5isr.renderer.utilities.RendererSettings; 021import armyc2.c5isr.renderer.utilities.SVGInfo; 022import armyc2.c5isr.renderer.utilities.SVGLookup; 023import armyc2.c5isr.renderer.utilities.SVGSymbolInfo; 024import armyc2.c5isr.renderer.utilities.SymbolID; 025import armyc2.c5isr.renderer.utilities.SymbolUtilities; 026 027/** 028 * This class is used for rendering icons that represent the single point graphics in the MilStd 2525. 029 * It can also be used for rendering icon previews for multipoint graphics. 030 */ 031public class MilStdIconRenderer 032/* implements IIconRenderer */ { 033 034 private String TAG = "MilStdIconRenderer"; 035 036 private static MilStdIconRenderer _instance = null; 037 private AtomicBoolean _initSuccess = new AtomicBoolean(false); 038 private SinglePointRenderer _SPR = null; 039 040 private SinglePointSVGRenderer _SPSVGR = null; 041 public static synchronized MilStdIconRenderer getInstance() 042 { 043 if (_instance == null) { 044 _instance = new MilStdIconRenderer(); 045 } 046 return _instance; 047 } 048 049 /** 050 * 051 * @param context 052 */ 053 public synchronized void init(Context context)// List<Typeface> fonts, List<String> xml 054 { 055 try { 056 if (!_initSuccess.get()) { 057 058 //test SVGLookup//////////////////////////////////////////////////////////////////// 059 SVGLookup.getInstance().init(context); 060 /*SVGInfo oct = SVGLookup.getInstance().getSVGLInfo("octagon"); 061 System.out.println(oct.toString());//*/ 062 063 //test MSLookup///////////////////////////////////////////////////////////////////// 064 MSLookup.getInstance().init(context); 065 066 /*MSInfo msi = MSLookup.getInstance().getMSLInfo("50110100",0);// 067 msi = MSLookup.getInstance().getMSLInfo("36190100",0);//"Non-Mine MineāLike Object, Bottom" 068 System.out.println(msi.getPath()); 069 System.out.println(msi.getName()); 070 msi = MSLookup.getInstance().getMSLInfo("01110300",0);//"Unmanned Aircraft (UA) / Unmanned Aerial Vehicle (UAV) / Unmanned Aircraft System (UAS) / Remotely Piloted Vehicle (RPV)" 071 System.out.println(msi.getPath()); 072 System.out.println(msi.getName());//*/ 073 074 DisplayMetrics dm = new DisplayMetrics(); 075 context.getSystemService(WindowManager.class).getDefaultDisplay().getRealMetrics(dm); 076 RendererSettings.getInstance().setDeviceDPI(dm.densityDpi); 077 RendererSettings.getInstance().setDeviceHeight(dm.heightPixels); 078 RendererSettings.getInstance().setDeviceWidth(dm.widthPixels); 079 080 //Country Codes 081 GENCLookup.getInstance().init(context); 082 083 // setup single point renderer 084 _SPR = SinglePointRenderer.getInstance(); 085 _SPSVGR = SinglePointSVGRenderer.getInstance(); 086 087 _initSuccess.set(true); 088 } 089 090 } catch (Exception exc) { 091 Log.e(TAG, exc.getMessage(), exc); 092 } 093 } 094 095 public synchronized boolean isReady() 096 { 097 return _initSuccess.get(); 098 } 099 100 // @Override 101 102 /** 103 * Checks symbol codes and returns whether they can be rendered. 104 * For multi-point graphics, modifiers are ignored because we don't need that 105 * information to show preview icons in the SymbolPicker. 106 * 107 * @param symbolID 20-30 digit 2525D Symbol ID Code 108 * @param attributes (currently unused) 109 * @return true if the basic form of the graphic can be rendered 110 */ 111 public Boolean CanRender(String symbolID, Map<String,String> attributes) 112 { 113 String message = ""; 114 try { 115 // Extract 8-digit ID to use with SVGLookup. 116 // MSLookup can handle long codes, but SVGLookup can't because it also takes other strings. 117 String lookupID = SymbolUtilities.getBasicSymbolID(symbolID); 118 String lookupSVGID = SVGLookup.getMainIconID(symbolID); 119 120 // Renderer only supports 2525D at the moment. 2525E will be in the future. 121 /* 122 int symStd = -1; 123 int version = SymbolID.getVersion(symbolID); 124 //SymbolID.Version_2525Dch1 125 //SymbolID.Version_2525E 126 */ 127 128 MSInfo msi = MSLookup.getInstance().getMSLInfo(symbolID); 129 if (msi == null) { 130 message = String.format("Cannot find %s in MSLookup", lookupID); 131 } else if (msi.getDrawRule() == DrawRules.DONOTDRAW) { 132 message = String.format("%s (%s) is DoNotDraw", lookupID, msi.getName()); 133 } else 134 { 135 int version = SymbolID.getVersion(symbolID); 136 SVGInfo si = SVGLookup.getInstance().getSVGLInfo(lookupSVGID,version); 137 if (si != null)// || (SymbolID.getEntityCode(symbolID)==000000 && SVGLookup.getInstance().getSVGLInfo(SVGLookup.getFrameID(symbolID)) != null)) 138 { 139 return true; 140 } 141 else 142 { 143 message = String.format("Cannot find %s (%s) in SVGLookup", lookupID, msi.getName()); 144 } 145 } 146 } catch (Exception exc) { 147 ErrorLogger.LogException("MilStdIconRenderer", "CanRender", exc); 148 } 149 // ErrorLogger.LogMessage(this.getClass().getName(), "CanRender()", message, Level.FINE); 150 Log.d("MilStdIconRenderer.CanRender()", message); 151 return false; 152 } 153 154 155 156 // @Override 157 public ImageInfo RenderIcon(String symbolID, Map<String,String> modifiers, 158 Map<String,String> attributes) 159 { 160 161 162 int ss = SymbolID.getSymbolSet(symbolID); 163 164 ImageInfo temp = null; 165 MSInfo msi = MSLookup.getInstance().getMSLInfo(symbolID); 166 if (msi == null) 167 { 168 //TODO: if null, try to fix the code so that something renders 169 /*symbolID = SymbolUtilities.reconcileSymbolID(symbolID); 170 basicSymbolID = SymbolUtilities.getBasicSymbolIDStrict(symbolID); 171 sd = SymbolDefTable.getInstance().getSymbolDef(basicSymbolID, symStd);//*/ 172 } 173 if (msi != null && msi.getDrawRule() == DrawRules.DONOTDRAW) { 174 return null; 175 } 176 177 if (ss==SymbolID.SymbolSet_ControlMeasure) 178 { 179 if (msi != null) { 180 //Point12 is actually a multipoint and 17 & 18 are rectangular target and sector range fan 181 if (SymbolUtilities.isMultiPoint(symbolID)==false) { 182 temp = _SPR.RenderSP(symbolID, modifiers, attributes); 183 } else { 184 temp = _SPR.RenderSP(symbolID, null, attributes); 185 } 186 } 187 } 188 else if(ss==SymbolID.SymbolSet_Atmospheric || 189 ss==SymbolID.SymbolSet_Oceanographic || 190 ss==SymbolID.SymbolSet_MeteorologicalSpace) 191 { 192 temp = _SPR.RenderSP(symbolID, modifiers, attributes); 193 } 194 else 195 { 196 temp = _SPR.RenderUnit(symbolID, modifiers, attributes); 197 } 198 199 return temp; 200 } 201 202 public SVGSymbolInfo RenderSVG(String symbolID, Map<String,String> modifiers, 203 Map<String,String> attributes) 204 { 205 206 //Update to use _SPSVGR.RenderUnit 207 int ss = SymbolID.getSymbolSet(symbolID); 208 209 ImageInfo temp = null; 210 SVGSymbolInfo svgTemp = null; 211 MSInfo msi = MSLookup.getInstance().getMSLInfo(symbolID); 212 if (msi == null) 213 { 214 //TODO: if null, try to fix the code so that something renders 215 /*symbolID = SymbolUtilities.reconcileSymbolID(symbolID); 216 basicSymbolID = SymbolUtilities.getBasicSymbolIDStrict(symbolID); 217 sd = SymbolDefTable.getInstance().getSymbolDef(basicSymbolID, symStd);//*/ 218 } 219 if (msi != null && msi.getDrawRule() == DrawRules.DONOTDRAW) 220 { 221 return null; 222 } 223 224 if (ss==SymbolID.SymbolSet_ControlMeasure) 225 { 226 if (msi != null) { 227 //Point12 is actually a multipoint and 17 & 18 are rectangular target and sector range fan 228 if (SymbolUtilities.isMultiPoint(symbolID)==false) { 229 svgTemp = _SPSVGR.RenderSP(symbolID, modifiers, attributes); 230 } else { 231 svgTemp = _SPSVGR.RenderSP(symbolID, null, attributes); 232 } 233 } 234 } 235 else if(ss==SymbolID.SymbolSet_Atmospheric || 236 ss==SymbolID.SymbolSet_Oceanographic || 237 ss==SymbolID.SymbolSet_MeteorologicalSpace) 238 { 239 svgTemp = _SPSVGR.RenderSP(symbolID, modifiers, attributes); 240 } 241 else 242 { 243 svgTemp = _SPSVGR.RenderUnit(symbolID, modifiers, attributes); 244 } 245 246 return svgTemp; 247 } 248 249 // @Override 250 public String getRendererID() 251 { 252 253 return "milstd2525"; 254 } 255 256 private Map<String,String> getDefaultAttributes(String symbolID) 257 { 258 Map<String,String> map = new HashMap<>(); 259 try { 260 if (symbolID == null || symbolID.length() != 15) { 261 if (symbolID == null) { 262 symbolID = "null"; 263 } 264 ErrorLogger.LogMessage("MilStdIconRenderer", "getDefaultAttributes", 265 "getDefaultAttributes passed bad symbolID: " + symbolID); 266 return null; 267 } 268 269 map.put(MilStdAttributes.Alpha, "1.0"); 270 if (SymbolUtilities.hasDefaultFill(symbolID)) { 271 map.put(MilStdAttributes.FillColor, 272 SymbolUtilities.getFillColorOfAffiliation(symbolID).toHexString()); 273 } 274 275 map.put(MilStdAttributes.LineColor, 276 SymbolUtilities.getLineColorOfAffiliation(symbolID).toHexString()); 277 278 map.put(MilStdAttributes.OutlineSymbol, "false"); 279 // attribute[MilStdAttributes.SymbolOutlineColor] = null; 280 // map.put(MilStdAttributes.OutlineWidth,"1"); 281 282 map.put(MilStdAttributes.DrawAsIcon, "false"); 283 284 RendererSettings rs = RendererSettings.getInstance(); 285 286 map.put(MilStdAttributes.KeepUnitRatio, "true"); 287 return map; 288 } catch (Exception exc) { 289 ErrorLogger.LogException("MilStdIconRenderer", "getDefaultAttributes", exc); 290 } 291 return map; 292 } 293 294 /** 295 * Add a custom framed symbol to the renderer's collection 296 * @param msInfo 297 * @param svgInfo 298 * @return 299 */ 300 public boolean AddCustomSymbol(MSInfo msInfo, SVGInfo svgInfo) 301 { 302 boolean success = false; 303 if(msInfo.getBasicSymbolID().equals(svgInfo.getID()))//Make sure IDs match 304 { 305 //Make sure entry isn't already there 306 if(MSLookup.getInstance().getMSLInfo(msInfo.getBasicSymbolID(),msInfo.getVersion())==null && 307 SVGLookup.getInstance().getSVGLInfo(svgInfo.getID(),msInfo.getVersion())==null) 308 { 309 if(MSLookup.getInstance().addCustomSymbol(msInfo)) 310 success = SVGLookup.getInstance().addCustomSymbol(svgInfo,msInfo.getVersion()); 311 } 312 } 313 else 314 { 315 ErrorLogger.LogMessage("Symbol Set and Entity Codes do not match", Level.INFO,false); 316 } 317 return success; 318 } 319}