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    }