// TwoDBilinearApproximation

        static double BilinearRecursive(Geo pointToInterpolate, Geo<float> northEast, Geo<float> northWest, Geo<float> southEast, Geo<float> southWest)
        {
            var bounds = GeoRect.Inflate(new GeoRect(northEast.Latitude, southWest.Latitude, northEast.Longitude, southWest.Longitude), 0.01);
            if (!bounds.Contains(pointToInterpolate)) 
                throw new ApplicationException("BilinearRecursive: PointToInterpolate is not within the southeast to northwest region");

            var zList = new List<double> { northEast.Data, northWest.Data, southEast.Data, southWest.Data };
            var zMin = zList.Min();
            var zMax = zList.Max();

            if ((zMax - zMin) < 1) return (zMax + zMin) / 2;

            var east = new Geo<float>(northEast.MidPoint(southEast), (northEast.Data + southEast.Data) / 2);
            var west = new Geo<float>(northWest.MidPoint(southWest), (northWest.Data + southWest.Data) / 2);
            var north = new Geo<float>(northEast.MidPoint(northWest), (northEast.Data + northWest.Data) / 2);
            var south = new Geo<float>(southEast.MidPoint(southWest), (southEast.Data + southWest.Data) / 2);
            var middle = new Geo<float>(north.MidPoint(south), (north.Data + south.Data) / 2);

            if (pointToInterpolate.Latitude <= middle.Latitude)   // If the point's latitude is less than or equal to the middle latitude, it's in the southern half of the current region
                return pointToInterpolate.Longitude <= middle.Longitude ? // If the point's longitude is is less than or equal to the middle longitude, it's in the western half of the current region
                    BilinearRecursive(pointToInterpolate, middle, west, south, southWest) : // Return the southwest quadrant
                    BilinearRecursive(pointToInterpolate, east, middle, southEast, south);  // Return the southeast quadrant

            // If we get here, the point is in the northern half of the current region 
            return pointToInterpolate.Longitude <= middle.Longitude ? // If the point's longitude is is less than or equal to the middle longitude, it's in the western half of the current region
                BilinearRecursive(pointToInterpolate, north, northWest, middle, west) : // Return the northwest quadrant
                BilinearRecursive(pointToInterpolate, northEast, north, east, middle);  // Return the northeast quadrant
        }