001package jmri.jmrix.rps; 002 003import java.io.File; 004import java.io.IOException; 005import java.util.List; 006import javax.vecmath.Point3d; 007import jmri.jmrit.XmlFile; 008import jmri.util.FileUtil; 009import org.jdom2.Attribute; 010import org.jdom2.Document; 011import org.jdom2.Element; 012import org.jdom2.ProcessingInstruction; 013import org.slf4j.Logger; 014import org.slf4j.LoggerFactory; 015 016/** 017 * Persist RPS configuration information. 018 * 019 * @author Bob Jacobsen Copyright 2007, 2008 020 */ 021public class PositionFile extends XmlFile { 022 023 Document doc; 024 Element root; 025 026 /** 027 * Initialize for writing information. 028 * <p> 029 * This is followed by multiple "set" calls, then a "store". 030 */ 031 public void prepare() { 032 root = new Element("rpsfile"); 033 doc = newDocument(root, dtdLocation + "rpsfile.dtd"); 034 035 // add XSLT processing instruction 036 // <?xml-stylesheet type="text/xsl" href="XSLT/rpsfile.xsl"?> 037 java.util.Map<String, String> m = new java.util.HashMap<String, String>(); 038 m.put("type", "text/xsl"); 039 m.put("href", xsltLocation + "rpsfile.xsl"); 040 ProcessingInstruction p = new ProcessingInstruction("xml-stylesheet", m); 041 doc.addContent(0, p); 042 043 } 044 045 public void setConstants(double vSound, int offset, String algorithm) { 046 Element v = new Element("vsound"); 047 v.addContent("" + vSound); 048 root.addContent(v); 049 050 Element o = new Element("offset"); 051 o.addContent("" + offset); 052 root.addContent(o); 053 054 Element a = new Element("algorithm"); 055 a.addContent(algorithm); 056 root.addContent(a); 057 } 058 059 public void setReceiver(int n, Receiver r) { 060 Element e = new Element("receiver"); 061 e.setAttribute("number", "" + n); 062 e.setAttribute("active", "" + (r.isActive() ? "true" : "false")); 063 e.setAttribute("mintime", "" + r.getMinTime()); 064 e.setAttribute("maxtime", "" + r.getMaxTime()); 065 e.addContent(positionElement(r.getPosition())); 066 root.addContent(e); 067 } 068 069 public void setReceiver(int n, Point3d p, boolean active) { 070 // allows defaults for min, max time 071 Element e = new Element("receiver"); 072 e.setAttribute("number", "" + n); 073 e.setAttribute("active", "" + (active ? "true" : "false")); 074 e.addContent(positionElement(p)); 075 root.addContent(e); 076 } 077 078 public void setCalibrationPoint(Point3d p, Reading r) { 079 Element e = new Element("calibrationpoint"); 080 e.addContent(positionElement(p)); 081 e.addContent(readingElement(r)); 082 root.addContent(e); 083 } 084 085 Element positionElement(Point3d p) { 086 Element e = new Element("position"); 087 Element x = new Element("x"); 088 x.addContent("" + p.x); 089 e.addContent(x); 090 Element y = new Element("y"); 091 y.addContent("" + p.y); 092 e.addContent(y); 093 Element z = new Element("z"); 094 z.addContent("" + p.z); 095 e.addContent(z); 096 return e; 097 } 098 099 public Point3d positionFromElement(Element position) { 100 Element e; 101 e = position.getChild("x"); 102 float x = Float.parseFloat(e.getText()); 103 104 e = position.getChild("y"); 105 float y = Float.parseFloat(e.getText()); 106 107 e = position.getChild("z"); 108 float z = Float.parseFloat(e.getText()); 109 110 return new Point3d(x, y, z); 111 } 112 113 Element readingElement(Reading r) { 114 Element e = new Element("reading"); 115 Element c = new Element("id"); 116 c.addContent("" + r.getId()); 117 e.addContent(c); 118 for (int i = 1; i <= r.getNValues(); i++) { 119 e.addContent(timeElement(r.getValue(i))); 120 } 121 return e; 122 } 123 124 public Reading readingFromElement(Element reading) { 125 String id = reading.getChild("id").getText(); 126 List<Element> kids = reading.getChildren("time"); 127 int count = kids.size(); 128 double[] vals = new double[count + 1]; 129 130 for (int i = 0; i < count; i++) { 131 Element e = kids.get(i); 132 double val = Double.parseDouble(e.getText()); 133 vals[i + 1] = val; // 1st item goes in element 1 134 } 135 136 return new Reading(id, vals); 137 } 138 139 Element timeElement(double time) { 140 Element e = new Element("time"); 141 e.addContent("" + time); 142 return e; 143 } 144 145 public void store(File file) throws IOException { 146 writeXML(file, doc); 147 } 148 149 /** 150 * Read in the file, and make available for examination. 151 * @param f file to load. 152 * @throws org.jdom2.JDOMException other errors 153 * @throws java.io.IOException error accessing file 154 */ 155 public void loadFile(File f) 156 throws org.jdom2.JDOMException, java.io.IOException { 157 158 root = rootFromFile(f); 159 } 160 161 public double getVSound() { 162 Element e = root.getChild("vsound"); 163 return Double.parseDouble(e.getText()); 164 } 165 166 public int getOffset() { 167 Element e = root.getChild("offset"); 168 return Integer.parseInt(e.getText()); 169 } 170 171 public String getAlgorithm() { 172 Element e = root.getChild("algorithm"); 173 return e.getText(); 174 } 175 176 /** 177 * FInd the highest numbered receiver in the file 178 * @return highest numbered receiver. 179 */ 180 public int maxReceiver() { 181 List<Element> kids = root.getChildren("receiver"); 182 int max = -1; 183 for (int i = 0; i < kids.size(); i++) { 184 Attribute a = kids.get(i).getAttribute("number"); 185 if (a == null) { 186 continue; 187 } 188 int n = -1; 189 try { 190 n = a.getIntValue(); 191 } catch (org.jdom2.DataConversionException e) { 192 log.error("in maxReceiver", e); 193 } 194 max = Math.max(max, n); 195 } 196 return max; 197 } 198 199 /** 200 * Get the nth receiver position in the file. 201 * 202 * @param n receiver index. 203 * @return null if not present 204 */ 205 public Point3d getReceiverPosition(int n) { 206 List<Element> kids = root.getChildren("receiver"); 207 for (int i = 0; i < kids.size(); i++) { 208 Element e = kids.get(i); 209 Attribute a = e.getAttribute("number"); 210 if (a == null) { 211 continue; 212 } 213 int num = -1; 214 try { 215 num = a.getIntValue(); 216 } catch (org.jdom2.DataConversionException ex) { 217 log.error("in getReceiverPosition", ex); 218 } 219 if (num == n) { 220 return positionFromElement(e.getChild("position")); 221 } 222 } 223 return null; 224 } 225 226 /** 227 * Get the nth receiver active state in the file. 228 * 229 * @param n receiver index. 230 * @return true if not present 231 */ 232 public boolean getReceiverActive(int n) { 233 List<Element> kids = root.getChildren("receiver"); 234 for (int i = 0; i < kids.size(); i++) { 235 Element e = kids.get(i); 236 Attribute a = e.getAttribute("number"); 237 if (a == null) { 238 continue; 239 } 240 int num = -1; 241 try { 242 num = a.getIntValue(); 243 } catch (org.jdom2.DataConversionException ex) { 244 log.error("in getReceiverActive", ex); 245 } 246 if (num != n) { 247 continue; 248 } 249 a = e.getAttribute("active"); 250 if (a == null) { 251 return true; // default value 252 } 253 if (a.getValue().equals("false")) { 254 return false; 255 } 256 return true; 257 } 258 return true; 259 } 260 261 /** 262 * Get the nth receiver min time. 263 * 264 * @param n receiver index. 265 * @return 0 if not present 266 */ 267 public int getReceiverMin(int n) { 268 List<Element> kids = root.getChildren("receiver"); 269 for (int i = 0; i < kids.size(); i++) { 270 Element e = kids.get(i); 271 Attribute a = e.getAttribute("number"); 272 if (a == null) { 273 continue; 274 } 275 int num = -1; 276 try { 277 num = a.getIntValue(); 278 } catch (org.jdom2.DataConversionException ex1) { 279 log.error("in getReceiverMin", ex1); 280 } 281 if (num != n) { 282 continue; 283 } 284 a = e.getAttribute("mintime"); 285 if (a == null) { 286 return 0; // default value 287 } 288 try { 289 return a.getIntValue(); 290 } catch (org.jdom2.DataConversionException ex2) { 291 return 0; 292 } 293 } 294 return 0; 295 } 296 297 /** 298 * Get the nth receiver max time. 299 * 300 * @param n receiver index. 301 * @return 0 if not present 302 */ 303 public int getReceiverMax(int n) { 304 List<Element> kids = root.getChildren("receiver"); 305 for (int i = 0; i < kids.size(); i++) { 306 Element e = kids.get(i); 307 Attribute a = e.getAttribute("number"); 308 if (a == null) { 309 continue; 310 } 311 int num = -1; 312 try { 313 num = a.getIntValue(); 314 } catch (org.jdom2.DataConversionException ex1) { 315 log.error("in getReceiverMax", ex1); 316 } 317 if (num != n) { 318 continue; 319 } 320 a = e.getAttribute("maxtime"); 321 if (a == null) { 322 return 99999; // default value 323 } 324 try { 325 return a.getIntValue(); 326 } catch (org.jdom2.DataConversionException ex2) { 327 return 99999; 328 } 329 } 330 return 99999; 331 } 332 333 /** 334 * Get the nth calibration position in the file. 335 * 336 * @param n calibration index. 337 * @return null if not present 338 */ 339 public Point3d getCalibrationPosition(int n) { 340 List<Element> kids = root.getChildren("calibrationpoint"); 341 if (n >= kids.size()) { 342 return null; 343 } 344 Element e = kids.get(n); 345 return positionFromElement(e.getChild("position")); 346 } 347 348 /** 349 * Get the nth calibration reading in the file. 350 * 351 * @param n reading index. 352 * @return null if not present 353 */ 354 public Reading getCalibrationReading(int n) { 355 List<Element> kids = root.getChildren("calibrationpoint"); 356 if (n >= kids.size()) { 357 return null; 358 } 359 Element e = kids.get(n); 360 return readingFromElement(e.getChild("reading")); 361 } 362 363 static public String defaultLocation() { 364 String location = FileUtil.getUserFilesPath() + "rps" + File.separator; 365 FileUtil.createDirectory(location); 366 return location; 367 } 368 369 static public String defaultFilename() { 370 return defaultLocation() + "positions.xml"; 371 } 372 373 // initialize logging 374 private final static Logger log = LoggerFactory.getLogger(PositionFile.class); 375 376}