public GridLayer RunSpeciesRichness()
        {
            // First load each of the layers...

            IsCancelled = false;

            var layers = new List <GridLayer>();

            foreach (string filename in LayerFiles)
            {
                ProgressMessage("Loading environmental layer {0}...", filename);
                layers.Add(new GridLayer(filename));
            }

            // Now for each point set, run the model...
            var resultLayers = new List <GridLayer>();

            Model.ProgressObserver = this;

            if (ProgressObserver != null)
            {
                ProgressObserver.ProgressMessage("Running models...");
            }

            var first = layers[0];

            int setIndex = 0;

            foreach (SpeciesRichnessPointSetViewModel pointset in MapPointSets)
            {
                _currentPointSet = pointset.Model;

                var percent = ((double)setIndex / (double)MapPointSets.Count()) * 100.0;

                if (ProgressObserver != null)
                {
                    ProgressObserver.ProgressMessage("Running model on pointset " + pointset.Name, percent);
                }

                FireStartPointSet(pointset.Model);

                var list = new List <MapPointSet>();
                list.Add(pointset.Model);
                var modelLayer = Model.RunModel(layers, list);
                if (modelLayer != null)
                {
                    if (RetainLayers)
                    {
                        pointset.Filename = string.Format("{0}{1}_{2}.grd", TempFileManager.GetTemporaryFolder(), SystemUtils.StripIllegalFilenameChars(pointset.Name), setIndex);
                        modelLayer.SaveToGRDFile(pointset.Filename);
                    }

                    resultLayers.Add(modelLayer);
                }

                if (IsCancelled)
                {
                    return(null);
                }

                FireEndPointSet(pointset.Model);

                setIndex++;
            }

            var target = new GridLayer(first.Width, first.Height)
            {
                DeltaLatitude = first.DeltaLatitude, DeltaLongitude = first.DeltaLongitude, Flags = first.Flags, Latitude0 = first.Latitude0, Longitude0 = first.Longitude0, NoValueMarker = 0
            };

            target.SetAllCells(0);
            foreach (GridLayer result in resultLayers)
            {
                for (int y = 0; y < target.Height; ++y)
                {
                    var lat = target.Latitude0 + (y * target.DeltaLatitude);            // Work out Lat. of this cell.
                    for (int x = 0; x < target.Width; ++x)
                    {
                        var lon  = target.Longitude0 + (x * target.DeltaLongitude); // Work out Long. of this cell.
                        var fVal = result.GetValueAt(lat, lon, result.NoValueMarker);
                        if (fVal == result.NoValueMarker)
                        {
                            target.SetCellValue(x, y, target.NoValueMarker);
                        }
                        else
                        {
                            if (fVal > CutOff)
                            {
                                var currentVal = target.GetCellValue(x, y);
                                target.SetCellValue(x, y, currentVal + 1);
                            }
                        }
                    }
                }
            }

            return(target);
        }
        protected override void RunModelImpl(GridLayer targetLayer, IEnumerable <GridLayer> layers, ModelPointSet points)
        {
            double fVal, fDestNoVal;
            bool   bTestFailed;

            // Work out ranges for the varying percentile bands across all layers...
            if (layers.Count() <= 0)
            {
                return;
            }

            List <EnvironmentalLayerRange[]> Range = new List <EnvironmentalLayerRange[]>();

            foreach (GridLayer layer in layers)
            {
                var array = new EnvironmentalLayerRange[4];
                array[0] = layer.GetRangeForPoints(points.Points, 0.0);
                array[1] = layer.GetRangeForPoints(points.Points, 0.05);
                array[2] = layer.GetRangeForPoints(points.Points, 0.1);
                array[3] = layer.GetRangeForPoints(points.Points, 0.25);
                Range.Add(array);
            }

            // For each cell for each layer...
            var firstLayer = layers.ElementAt(0);

            fDestNoVal = firstLayer.NoValueMarker;

            targetLayer.SetAllCells(fDestNoVal);

            for (int y = 0; y < firstLayer.Height; ++y)
            {
                for (int x = 0; x < firstLayer.Width; ++x)
                {
                    // First test %0 - %100
                    bTestFailed = false;
                    for (int i = 0; i < layers.Count(); ++i)
                    {
                        var layer = layers.ElementAt(i);
                        fVal = layer.GetCellValue(x, y);
                        if (fVal == layer.NoValueMarker)
                        {
                            bTestFailed = true;
                            break;
                        }
                        else
                        {
                            if ((fVal < Range[i][0].Min) || (fVal > Range[i][0].Max))   // %0-%100
                            {
                                bTestFailed = true;
                                targetLayer.SetCellValue(x, y, fDestNoVal);
                                break;
                            }
                        }
                    }

                    if (!bTestFailed)
                    {
                        targetLayer.SetCellValue(x, y, 1);
                        // Second test %5 - %95
                        for (int i = 0; i < layers.Count(); ++i)
                        {
                            var layer = layers.ElementAt(i);
                            fVal = layer.GetCellValue(x, y);
                            if ((fVal < Range[i][1].Min) || (fVal > Range[i][1].Max))   // %5-%95
                            {
                                bTestFailed = true;
                                break;
                            }
                        }

                        if (!bTestFailed)
                        {
                            targetLayer.SetCellValue(x, y, 2);
                            for (int i = 0; i < layers.Count(); ++i)
                            {
                                var layer = layers.ElementAt(i);
                                fVal = layer.GetCellValue(x, y);
                                if ((fVal < Range[i][2].Min) || (fVal > Range[i][2].Max))   // %10-%90
                                {
                                    bTestFailed = true;
                                    break;
                                }
                            }

                            if (!bTestFailed)
                            {
                                targetLayer.SetCellValue(x, y, 3);
                                for (int i = 0; i < layers.Count(); ++i)
                                {
                                    var layer = layers.ElementAt(i);
                                    fVal = layer.GetCellValue(x, y);
                                    if ((fVal < Range[i][3].Min) || (fVal > Range[i][3].Max))   // %25-%75
                                    {
                                        bTestFailed = true;
                                        break;
                                    }
                                }

                                if (!bTestFailed)
                                {
                                    targetLayer.SetCellValue(x, y, 4);
                                }
                            }
                        }
                    }
                }

                if ((y % 20) == 0)
                {
                    int percent = (int)(((float)y / (float)targetLayer.Height) * (float)100);
                    if (ProgressObserver != null)
                    {
                        ProgressObserver.ProgressMessage("Running BOXCAR Model...", percent);
                    }

                    if (IsCancelled)
                    {
                        return;
                    }
                }
            }

            if (ProgressObserver != null)
            {
                ProgressObserver.ProgressMessage("Running BOXCAR Model...", 100);
            }
        }
        protected override void RunModelImpl(GridLayer targetLayer, IEnumerable<GridLayer> layers, ModelPointSet points)
        {
            double fVal, fDestNoVal;
            bool bTestFailed;

            // Work out ranges for the varying percentile bands across all layers...
            if (layers.Count() <= 0) {
                return;
            }

            List<EnvironmentalLayerRange[]> Range = new List<EnvironmentalLayerRange[]>();
            foreach (GridLayer layer in layers) {
                var array = new EnvironmentalLayerRange[4];
                array[0] = layer.GetRangeForPoints(points.Points, 0.0);
                array[1] = layer.GetRangeForPoints(points.Points, 0.05);
                array[2] = layer.GetRangeForPoints(points.Points, 0.1);
                array[3] = layer.GetRangeForPoints(points.Points, 0.25);
                Range.Add(array);
            }

            // For each cell for each layer...
            var firstLayer = layers.ElementAt(0);
            fDestNoVal = firstLayer.NoValueMarker;

            targetLayer.SetAllCells(fDestNoVal);

            for (int y = 0; y < firstLayer.Height; ++y) {
                for (int x = 0; x < firstLayer.Width; ++x) {
                    // First test %0 - %100
                    bTestFailed = false;
                    for (int i = 0; i < layers.Count(); ++i) {
                        var layer = layers.ElementAt(i);
                        fVal = layer.GetCellValue(x, y);
                        if (fVal == layer.NoValueMarker) {
                            bTestFailed = true;
                            break;
                        } else {
                            if ((fVal < Range[i][0].Min) || (fVal > Range[i][0].Max)) { // %0-%100
                                bTestFailed = true;
                                targetLayer.SetCellValue(x, y, fDestNoVal);
                                break;
                            }
                        }
                    }

                    if (!bTestFailed) {

                        targetLayer.SetCellValue(x, y, 1);
                        // Second test %5 - %95
                        for (int i = 0; i < layers.Count(); ++i) {
                            var layer = layers.ElementAt(i);
                            fVal = layer.GetCellValue(x, y);
                            if ((fVal < Range[i][1].Min) || (fVal > Range[i][1].Max)) { // %5-%95
                                bTestFailed = true;
                                break;
                            }
                        }

                        if (!bTestFailed) {
                            targetLayer.SetCellValue(x, y, 2);
                            for (int i = 0; i < layers.Count(); ++i) {
                                var layer = layers.ElementAt(i);
                                fVal = layer.GetCellValue(x, y);
                                if ((fVal < Range[i][2].Min) || (fVal > Range[i][2].Max)) { // %10-%90
                                    bTestFailed = true;
                                    break;
                                }
                            }

                            if (!bTestFailed) {
                                targetLayer.SetCellValue(x, y, 3);
                                for (int i = 0; i < layers.Count(); ++i) {
                                    var layer = layers.ElementAt(i);
                                    fVal = layer.GetCellValue(x, y);
                                    if ((fVal < Range[i][3].Min) || (fVal > Range[i][3].Max)) { // %25-%75
                                        bTestFailed = true;
                                        break;
                                    }
                                }

                                if (!bTestFailed) {
                                    targetLayer.SetCellValue(x, y, 4);
                                }
                            }
                        }
                    }
                }

                if ((y % 20) == 0) {
                    int percent = (int)(((float)y / (float)targetLayer.Height) * (float)100);
                    if (ProgressObserver != null) {
                        ProgressObserver.ProgressMessage("Running BOXCAR Model...", percent);
                    }

                    if (IsCancelled) {
                        return;
                    }
                }
            }

            if (ProgressObserver != null) {
                ProgressObserver.ProgressMessage("Running BOXCAR Model...", 100);
            }
        }