001    /**
002     * 
003     */
004    package org.wdssii.core;
005    
006    import org.apache.commons.logging.Log;
007    import org.apache.commons.logging.LogFactory;
008    
009    import ucar.ma2.ArrayFloat;
010    import ucar.ma2.ArrayInt;
011    import ucar.ma2.ArrayShort;
012    
013    /**
014     * @author lakshman
015     *
016     */
017    public class NetcdfSparseGrid {
018            private ArrayShort pixelx;
019            private ArrayShort pixely;
020            private ArrayInt pixelcount;
021            private ArrayFloat values;
022            private static Log log = LogFactory.getLog(NetcdfSparseGrid.class);
023            public NetcdfSparseGrid(float[][] inValues, float backgroundValue){
024                    int xdim = inValues.length;
025                    int ydim = inValues[0].length;
026                    // find the number of runs in sparse array
027                    int N = 0;
028                    boolean inRun = false;
029                    float prevValue = backgroundValue;
030                    for (int i=0; i < xdim; ++i){
031                            for (int j=0; j < ydim; ++j){
032                                    if (inRun){
033                                            if (inValues[i][j] == backgroundValue ){
034                                                    inRun = false;
035                                            }
036                                            else if (inValues[i][j] != prevValue){
037                                                    prevValue = inValues[i][j];
038                                                    ++N;
039                                            }
040                                    } else if (inValues[i][j] != backgroundValue){
041                                            prevValue = inValues[i][j];
042                                            ++N;
043                                            inRun = true;
044                                    }
045                            }
046                    }
047                    if (log.isDebugEnabled()){
048                            log.debug("SparseGrid compression reduced size of grid from " + (xdim*ydim) + " to " + N);
049                    }
050                    
051                    // special processing for N=0 since netcdf has problems with zero-length arrays
052                    boolean zeroN = (N == 0);
053                    if (zeroN){
054                            N = 1;
055                    }
056                    
057                    // create sparse grid array
058                    pixelx = new ArrayShort(new int[]{N});
059                    pixely = new ArrayShort(new int[]{N});
060                    pixelcount = new ArrayInt(new int[]{N});
061                    values = new ArrayFloat(new int[]{N});
062                    
063                    if (zeroN){
064                            pixelx.set(pixelx.getIndex(), (short)0);
065                            pixely.set(pixely.getIndex(), (short)0);
066                            pixelcount.set(pixelcount.getIndex(),1);
067                            values.set(values.getIndex(),backgroundValue);
068                            return;
069                    }
070                    
071                    N = -1;
072                    ucar.ma2.Index nIndex = pixelx.getIndex();
073                    inRun = false;
074                    prevValue = backgroundValue;
075                    for (short i=0; i < xdim; ++i){
076                            for (short j=0; j < ydim; ++j){
077                                    if (inRun){
078                                            if (inValues[i][j] == backgroundValue ){
079                                                    inRun = false;
080                                            }
081                                            else if (inValues[i][j] != prevValue){
082                                                    prevValue = inValues[i][j];
083                                                    ++N;
084                                                    nIndex.set(N);
085                                                    pixelx.set(nIndex,i);
086                                                    pixely.set(nIndex,j);
087                                                    pixelcount.set(nIndex,1);
088                                                    values.set(nIndex,prevValue);
089                                            } else {
090                                                    pixelcount.set(nIndex, pixelcount.get(nIndex) + 1);
091                                            }
092                                    } else if (inValues[i][j] != backgroundValue){
093                                            prevValue = inValues[i][j];
094                                            ++N;
095                                            nIndex.set(N);
096                                            pixelx.set(nIndex,i);
097                                            pixely.set(nIndex,j);
098                                            pixelcount.set(nIndex,1);
099                                            values.set(nIndex,prevValue);
100                                            inRun = true;
101                                    }
102                            }
103                    }       
104            }
105    
106            public ArrayInt getPixelcount() {
107                    return pixelcount;
108            }
109    
110            public ArrayShort getPixelx() {
111                    return pixelx;
112            }
113    
114            public ArrayShort getPixely() {
115                    return pixely;
116            }
117    
118            public ArrayFloat getValues() {
119                    return values;
120            }
121            
122            
123            public static float computeSparseGridRatio(float[][] inValues, float backgroundValue){
124                    int xdim = inValues.length;
125                    int ydim = inValues[0].length;
126                    // find the number of runs in sparse array
127                    int N = 0;
128                    boolean inRun = false;
129                    float prevValue = backgroundValue;
130                    for (int i=0; i < xdim; ++i){
131                            for (int j=0; j < ydim; ++j){
132                                    if (inRun){
133                                            if (inValues[i][j] == backgroundValue ){
134                                                    inRun = false;
135                                            }
136                                            else if (inValues[i][j] != prevValue){
137                                                    prevValue = inValues[i][j];
138                                                    ++N;
139                                            }
140                                    } else if (inValues[i][j] != backgroundValue){
141                                            prevValue = inValues[i][j];
142                                            ++N;
143                                            inRun = true;
144                                    }
145                            }
146                    }
147                    float origSize = xdim*ydim;
148                    float newSize = N * 4;
149                    return (newSize / origSize);
150            }
151    }