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 }