001 /** 002 * 003 */ 004 package org.wdssii.core; 005 006 import java.util.ArrayList; 007 import java.util.List; 008 009 import org.apache.commons.logging.Log; 010 import org.apache.commons.logging.LogFactory; 011 import org.w3c.dom.Element; 012 import org.w3c.dom.NodeList; 013 014 /** 015 * VolumeCoveragePattern from w2config/vcp 016 * 017 * @author lakshman 018 * 019 */ 020 public class VCP { 021 private static Log log = LogFactory.getLog(VCP.class); 022 023 private static List<VCP> vcps = new ArrayList<VCP>(); 024 025 private int vcp; 026 027 private boolean isNexrad = true; 028 029 private boolean isMultiPRF = false; 030 031 private boolean isClearAir = true; 032 033 private boolean canCache = true; 034 035 private int totalTime = -20; 036 037 private float[] scans; 038 039 private float[] elevations; 040 041 public boolean isClearAir() { 042 return isClearAir; 043 } 044 045 public boolean isMultiPRF() { 046 return isMultiPRF; 047 } 048 049 public boolean isNexrad() { 050 return isNexrad; 051 } 052 053 public int getTotalTime() { 054 return totalTime; 055 } 056 057 public int getVcp() { 058 return vcp; 059 } 060 061 public static VCP getVCP(int vcp) { 062 for (VCP v : vcps) { 063 if (v.vcp == vcp) { 064 return v; 065 } 066 } 067 VCP v = new VCP(vcp); 068 if (v.canCache && v.vcp > 0) { 069 vcps.add(v); 070 } 071 return v; 072 } 073 074 private VCP(int vcp) { 075 try { 076 this.vcp = vcp; 077 Element vcpel = W2Config.getFileElement("vcp/vcp" + vcp); 078 isNexrad = XMLUtil.getBooleanAttribute(vcpel, "isNexrad", true); 079 isMultiPRF = XMLUtil 080 .getBooleanAttribute(vcpel, "isMultiPRF", false); 081 isClearAir = XMLUtil.getBooleanAttribute(vcpel, "isClearAir", true); 082 canCache = XMLUtil.getBooleanAttribute(vcpel, "canCache", true); 083 totalTime = XMLUtil.getIntegerAttribute(vcpel, "totalTime", -20); 084 085 NodeList angleElements = vcpel.getElementsByTagName("angle"); 086 scans = new float[angleElements.getLength()]; 087 int numElev = 1; // 0th 088 for (int i = 0; i < scans.length; ++i) { 089 Element ang = (Element) angleElements.item(i); 090 scans[i] = Float.parseFloat(ang.getTextContent()); 091 if (i > 0 && scans[i] != scans[i - 1]) { 092 ++numElev; 093 } 094 } 095 elevations = new float[numElev]; 096 numElev = 0; 097 for (int i = 0; i < scans.length; ++i) { 098 elevations[numElev] = scans[i]; 099 if (i > 0 && scans[i] != scans[i - 1]) { 100 ++numElev; 101 } 102 } 103 if (log.isInfoEnabled()) { 104 log.info("Found " + elevations.length + " angles in " 105 + scans.length + " scans for VCP " + vcp); 106 } 107 } catch (Exception e) { 108 log.warn(e); 109 this.vcp = -1; 110 } 111 } 112 113 /** tilt number starts at 1 */ 114 public float getElevation(int tilt) { 115 return elevations[tilt - 1]; 116 } 117 118 /** tilts are numbers 1,2, ... */ 119 public int getLastTilt() { 120 return elevations.length; 121 } 122 123 /** tilts are numbered 1,2, ... */ 124 public int getTiltNumber(float elev) { 125 float mindiff = 360; 126 int closest_tilt = 0; 127 128 for (int i = 0; i < elevations.length; ++i) { 129 float diff = Math.abs(elev - elevations[i]); 130 if (diff < mindiff) { 131 mindiff = diff; 132 closest_tilt = i + 1; // tilts are numbered starting at 1 133 } 134 } 135 136 return closest_tilt; 137 138 } 139 }