/alaspatial/src/main/java/org/ala/spatial/analysis/index/ValueCorrection.java

http://alageospatialportal.googlecode.com/ · Java · 295 lines · 172 code · 35 blank · 88 comment · 54 complexity · f812e6e940ceadef26dc882937d69160 MD5 · raw file

  1. /*
  2. * To change this template, choose Tools | Templates
  3. * and open the template in the editor.
  4. */
  5. package org.ala.spatial.analysis.index;
  6. import java.io.BufferedReader;
  7. import java.io.FileReader;
  8. /**
  9. * Some value correction while parsing strings.
  10. *
  11. * Permitted units:
  12. * mm, cm, km
  13. *
  14. * Permitted types (in m):
  15. * depth, >= 0
  16. * altitude, <= 10,000,000
  17. * year, > 1600 and <= current
  18. * distance, >= 0 and <= 20,000,000
  19. *
  20. * If invalid value, default to Double.NaN, Float.NaN, Integer.MIN_VALUE.
  21. *
  22. * @author Adam
  23. */
  24. public class ValueCorrection {
  25. final static String[] unitsList = {"mm", "cm", "m", "km"};
  26. final static double[] unitsListScale = {0.001, 0.01, 1, 1000};
  27. final static String[] typesList = {"depth", "altitude", "year", "distance"};
  28. final static double[] typesListMin = {0, Double.NEGATIVE_INFINITY, 1000, 0};
  29. final static double[] typesListMax = {Double.POSITIVE_INFINITY, 10000000, java.util.Calendar.getInstance().get(java.util.Calendar.YEAR), Double.POSITIVE_INFINITY};
  30. static public int correctToInt(String targetUnits, String validationType, String stringValue) {
  31. int i = scaleInt(targetUnits, stringValue);
  32. i = correct(i, validationType);
  33. return i;
  34. }
  35. static public double correctToDouble(String targetUnits, String validationType, String stringValue) {
  36. double d = scaleDouble(targetUnits, stringValue);
  37. d = correct(d, validationType);
  38. return d;
  39. }
  40. /**
  41. * Attempt to read an Integer to the target units.
  42. *
  43. * test for < #
  44. * test for < # units
  45. * test for # - #
  46. * test for # units - #
  47. * test for # units - # units
  48. * test for # - # units
  49. *
  50. * @param targetUnits
  51. * @param validationType
  52. * @param stringValue
  53. * @return
  54. */
  55. static int scaleInt(String targetUnits, String stringValue) {
  56. int vi = Integer.MIN_VALUE;
  57. //test zero length
  58. if (stringValue.length() == 0) {
  59. return vi;
  60. }
  61. //attempt parse
  62. try {
  63. return Integer.parseInt(stringValue);
  64. } catch (Exception e) {
  65. }
  66. stringValue = clean(stringValue);
  67. //test for 'units' at end
  68. int unitsPos = getUnitsPos(stringValue);
  69. double multiplier = getUnitsMultiplier(unitsPos, targetUnits);
  70. //fix stringValue for unitsPos >= 0
  71. if (unitsPos >= 0) {
  72. stringValue = stringValue.substring(0, stringValue.length() - unitsList[unitsPos].length());
  73. }
  74. if (stringValue.length() > 0 && stringValue.charAt(0) == '<') {
  75. //test for < #
  76. //test for < # units
  77. stringValue = stringValue.substring(1);
  78. } else {
  79. int dashPos = stringValue.indexOf('-', 1);
  80. if (dashPos > 0) {
  81. //test for # - #
  82. //test for # units - #
  83. //test for # units - # units
  84. //test for # - # units
  85. stringValue = stringValue.substring(dashPos + 1);
  86. }
  87. }
  88. //parse remaining stringValue as int and apply multiplier
  89. try {
  90. vi = (int) (Integer.parseInt(stringValue) * multiplier);
  91. } catch (Exception e) {
  92. }
  93. //failed 2nd parse as int, try as double and apply multiplier
  94. if (vi == Integer.MIN_VALUE) {
  95. try {
  96. vi = (int) (Double.parseDouble(stringValue) * multiplier);
  97. } catch (Exception e) {
  98. }
  99. }
  100. return vi;
  101. }
  102. /**
  103. * Attempt to read an Integer to the target units.
  104. *
  105. * test for < #
  106. * test for < # units
  107. * test for # - #
  108. * test for # units - #
  109. * test for # units - # units
  110. * test for # - # units
  111. *
  112. * @param targetUnits
  113. * @param validationType
  114. * @param stringValue
  115. * @return
  116. */
  117. static double scaleDouble(String targetUnits, String stringValue) {
  118. double vd = Double.NaN;
  119. //test zero length
  120. if (stringValue.length() == 0) {
  121. return vd;
  122. }
  123. //attempt parse
  124. try {
  125. return Double.parseDouble(stringValue);
  126. } catch (Exception e) {
  127. }
  128. stringValue = clean(stringValue);
  129. //test for 'units' at end
  130. int unitsPos = getUnitsPos(stringValue);
  131. double multiplier = getUnitsMultiplier(unitsPos, targetUnits);
  132. //fix stringValue for unitsPos >= 0
  133. if (unitsPos >= 0) {
  134. stringValue = stringValue.substring(0, stringValue.length() - unitsList[unitsPos].length());
  135. }
  136. if (stringValue.length() > 0 && stringValue.charAt(0) == '<') {
  137. //test for < #
  138. //test for < # units
  139. stringValue = stringValue.substring(1);
  140. } else {
  141. int dashPos = stringValue.indexOf('-', 1);
  142. if (dashPos > 0) {
  143. //test for # - #
  144. //test for # units - #
  145. //test for # units - # units
  146. //test for # - # units
  147. stringValue = stringValue.substring(dashPos + 1);
  148. }
  149. }
  150. //parse remaining stringValue as double and apply multiplier
  151. try {
  152. vd = Double.parseDouble(stringValue) * multiplier;
  153. } catch (Exception e) {
  154. }
  155. return vd;
  156. }
  157. private static String clean(String value) {
  158. //remove spaces
  159. value = value.replace(" ", "");
  160. //remove trailing non-unit or number characters
  161. int i;
  162. boolean remove = true;
  163. while (remove && value.length() > 0) {
  164. char end = value.charAt(value.length() - 1);
  165. if (end <= '9' && end >= '0') {
  166. break;
  167. } else {
  168. // remove = true;
  169. // for(i=0;i<unitsList.length;i++) {
  170. // if(end == unitsList[i].charAt(unitsList[i].length()-1)) {
  171. // remove = false;
  172. // break;
  173. // }
  174. // }
  175. // if(remove) {
  176. // value = value.substring(0, value.length() - 1);
  177. // }
  178. //only permit removal of '.'
  179. if (end == '.') {
  180. value = value.substring(0, value.length() - 1);
  181. remove = true;
  182. } else {
  183. remove = false;
  184. }
  185. }
  186. }
  187. return value.trim().toLowerCase();
  188. }
  189. private static int getUnitsPos(String stringValue) {
  190. int pos = -1;
  191. if (stringValue.length() > 0) {
  192. for (int i = 0; i < unitsList.length; i++) {
  193. if (stringValue.endsWith(unitsList[i])) {
  194. char c = stringValue.charAt(stringValue.length() - unitsList[i].length() - 1);
  195. if (c <= '9' && c >= '0') {
  196. pos = i;
  197. break;
  198. }
  199. }
  200. }
  201. }
  202. return pos;
  203. }
  204. private static double getUnitsMultiplier(int unitsPos, String targetUnits) {
  205. if (unitsPos < 0 || targetUnits == null) {
  206. return 1;
  207. }
  208. double multiplier = 1;
  209. for (int i = 0; i < unitsList.length; i++) {
  210. if (targetUnits.equals(unitsList[i])) {
  211. multiplier = unitsListScale[unitsPos] / unitsListScale[i];
  212. }
  213. }
  214. return multiplier;
  215. }
  216. public static void main(String[] args) {
  217. String filename = "d:\\list.csv";
  218. try {
  219. BufferedReader r = new BufferedReader(new FileReader(filename));
  220. String s;
  221. System.out.println("original value,corrected double,corrected int");
  222. while ((s = r.readLine()) != null) {
  223. double d = correctToDouble("m", "distance", s);
  224. int i = correctToInt("m", "distance", s);
  225. System.out.println(s + "," + ((Double.isNaN(d)) ? "" : d) + "," + ((i == Integer.MIN_VALUE) ? "" : i));
  226. }
  227. r.close();
  228. } catch (Exception e) {
  229. e.printStackTrace();
  230. }
  231. }
  232. private static int correct(int v, String validationType) {
  233. if (validationType != null && v != Integer.MIN_VALUE) {
  234. for (int i = 0; i < typesList.length; i++) {
  235. if (typesList[i].equals(validationType)) {
  236. //test
  237. if (v < typesListMin[i] || v > typesListMax[i]) {
  238. v = Integer.MIN_VALUE;
  239. }
  240. break;
  241. }
  242. }
  243. }
  244. return v;
  245. }
  246. private static double correct(double v, String validationType) {
  247. if (validationType != null && !Double.isNaN(v)) {
  248. for (int i = 0; i < typesList.length; i++) {
  249. if (typesList[i].equals(validationType)) {
  250. //test
  251. if (v < typesListMin[i] || v > typesListMax[i]) {
  252. v = Double.NaN;
  253. }
  254. break;
  255. }
  256. }
  257. }
  258. return v;
  259. }
  260. }