// convert any numeric byte type to a float
        public static float byteToFloat(byte[] bytes, NC_TYPE type)
        {
            switch (type)
            {
            case NC_TYPE.NC_SHORT:
                return(Convert.ToSingle(NetCDFTools.byteToShort(bytes)));

            case NC_TYPE.NC_INT:
                return(Convert.ToSingle(NetCDFTools.byteToInt(bytes)));

            case NC_TYPE.NC_DOUBLE:
                return(Convert.ToSingle(NetCDFTools.byteToDouble(bytes)));
            }

            return(NetCDFTools.byteToFloat(bytes));
        }
        /// <summary>
        /// Constructor for interpreting from an NC file
        /// </summary>
        /// <param name="head">the raw NC data</param>
        public GeoSpatialData(Header head)
        {
            Variable latVar  = null;
            Variable lngVar  = null;
            Variable timeVar = null;
            Variable dataVar = null;

            Dimension[] dataDimensions = null;

            int       latDimID  = 0;
            Dimension latDim    = null;
            int       lngDimID  = 0;
            Dimension lngDim    = null;
            int       timeDimID = 0;
            Dimension timeDim   = null;

            dataDimensions = new Dimension[3];

            foreach (Variable v in head.var_list)
            {
                if (v.name.Equals("latitude") || v.name.Equals("lat"))
                {
                    latVar   = v;
                    latDimID = v.dimid[0];
                    latDim   = head.dim_list.ElementAt(latDimID);
                    dataDimensions[latDimID] = latDim;
                }
                else if (v.name.Equals("longitude") || v.name.Equals("lng") || v.name.Equals("long"))
                {
                    lngVar   = v;
                    lngDimID = v.dimid[0];
                    lngDim   = head.dim_list.ElementAt(lngDimID);
                    dataDimensions[lngDimID] = lngDim;
                }
                else if (v.name.Equals("time"))
                {
                    timeVar   = v;
                    timeDimID = v.dimid[0];
                    timeDim   = head.dim_list.ElementAt(timeDimID);
                    dataDimensions[timeDimID] = timeDim;
                }
                else
                {
                    dataVar = v;
                }
            }

            // pull out the relevant attributes from the dataVar
            foreach (Attribute a in dataVar.vatt_list)
            {
                if (a.name == "long_name")
                {
                    this.data_name = NetCDFTools.byteToString(a.values);
                }
                else if (a.name == "units")
                {
                    this.units = NetCDFTools.byteToString(a.values);
                }
            }
            this.data_type          = dataVar.name;
            this.data_missing_value = dataVar.missing_value;
            this.data_max           = dataVar.valid_max;
            this.data_min           = dataVar.valid_min;

            // convert each set of data into its real format
            this.data = new float[timeVar.length, latVar.length, lngVar.length];
            for (int i = 0; i < dataDimensions[0].length; i++)
            {
                for (int j = 0; j < dataDimensions[1].length; j++)
                {
                    for (int k = 0; k < dataDimensions[2].length; k++)
                    {
                        int index = i * dataDimensions[1].length * dataDimensions[2].length +
                                    j * dataDimensions[2].length +
                                    k;

                        data[i, j, k] = NetCDFTools.byteToFloat(dataVar.data[index], dataVar.type);
                    }
                }
            }

            this.lat = new decimal[latVar.length];
            for (int i = 0; i < this.lat.Length; i++)
            {
                this.lat[i] = (decimal)NetCDFTools.byteToFloat(latVar.data[i], latVar.type);
            }

            this.lng = new decimal[lngVar.length];
            for (int i = 0; i < this.lng.Length; i++)
            {
                this.lng[i] = (decimal)NetCDFTools.byteToFloat(lngVar.data[i], lngVar.type);
            }

            DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);

            this.time     = new int[timeVar.length];
            this.dateTime = new DateTime[timeVar.length];
            for (int i = 0; i < this.time.Length; i++)
            {
                this.time[i]     = NetCDFTools.byteToInt(timeVar.data[i]);
                this.dateTime[i] = epoch.AddSeconds(this.time[i]);
            }
        }