Example #1
0
        /// <summary>
        /// Executes the Area tool with programatic input
        /// Ping delete static for external testing
        /// </summary>
        /// <param name="input">The input raster</param>
        /// <param name="output">The output polygon feature set</param>
        /// <param name="zField">The field name containing the values to interpolate</param>
        /// <param name="cellSize">The double geographic size of the raster cells to create</param>
        /// <param name="power">The double power representing the inverse</param>
        /// <param name="neighborType">Fixed distance of fixed number of neighbors</param>
        /// <param name="pointCount">The number of neighbors to include if the neighborhood type
        /// is Fixed</param>
        /// <param name="distance">Points further from the raster cell than this distance are not included 
        /// in the calculation if the neighborhood type is Fixed Distance.</param>
        /// <param name="output">The output raster where values are stored.  The filename is used, but the number
        /// of rows and columns will be computed from the cellSize and input featureset</param>
        /// <param name="cancelProgressHandler">A progress handler for receiving progress messages</param>
        /// <returns>A boolean, true if the IDW process worked correctly</returns>
        public bool Execute(IFeatureSet input, string zField, double cellSize, double power, NeighborhoodType neighborType, int pointCount, double distance, IRaster output, ICancelProgressHandler cancelProgressHandler)
        {
           
            //Validates the input and output data
            if (input == null || output == null)
                return false;

            //If the cellSize is 0 we calculate a cellsize based on the input extents
            if (cellSize == 0)
                cellSize = input.Envelope.Width / 255;

            //Defines the dimesions and position of the raster
            int numColumns = Convert.ToInt32(Math.Round(input.Envelope.Width / cellSize));
            int numRows = Convert.ToInt32(Math.Round(input.Envelope.Height / cellSize));
          
            output = Raster.Create(output.Filename, "",numColumns, numRows, 1, typeof(double), new[] {""} );

            output.CellHeight = cellSize;
            output.CellWidth = cellSize;
            output.Xllcenter = input.Envelope.Minimum.X + (cellSize/2);
            output.Yllcenter = input.Envelope.Minimum.Y + (cellSize/2);

            //Used to calculate progress
            int lastUpdate=0;

            //Populates the KD tree
            MapWindow.Analysis.Topology.KDTree.KDTree kd = new MapWindow.Analysis.Topology.KDTree.KDTree(2);
            List<int> randomList = new List<int>();
            for (int i = 0; i < input.Features.Count; i++)
            {
                randomList.Add(i);
            }

            Random rnd = new Random();
            List<int> completed = new List<int>();
            while (randomList.Count > 0)
            {
                int index = rnd.Next(0,randomList.Count -1);
                Coordinate coord = input.Features[randomList[index]].Coordinates[0];
                while (kd.Search(coord.ToArray()) != null)
                    coord.X = coord.X * 1.000000000000001D;                    
                kd.Insert(coord.ToArray(), input.Features[randomList[index]]);
                completed.Add(randomList[index]);
                randomList.RemoveAt(index);
            }

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

            //Makes sure we don't try to search for more points then exist
            if (kd.Count < pointCount)
                pointCount = kd.Count;

            if (neighborType == NeighborhoodType.FixedCount)
            {
                //we add all the old features to output
                for (int x = 0; x < numColumns; x++)
                {
                    for (int y = 0; y < numRows; y++)
                    {                     
                        //Gets the pointCount number of cells closest to the current cell
                        Coordinate cellCenter = output.CellToProj(y, x);
                        Double[] pixelCoord = new double[2];
                        pixelCoord[0] = output.CellToProj(y, x).X;
                        pixelCoord[1] = output.CellToProj(y, x).Y;
                        sw.Start();
                        object[] result = kd.Nearest(pixelCoord, pointCount);
                        sw.Stop();

                        //Sets up the IDW numerator and denominator
                        double top = 0;
                        double bottom = 0;
                        foreach (object feat in result)
                        {
                              IFeature featurePt = feat as Feature;
                              if (featurePt == null) continue;
                              double distanceToCell = cellCenter.Distance(featurePt.Coordinates[0]);
                              if (distanceToCell <= distance || distance == 0)
                              {
                                  //If we can't convert the value to a double throw it out
                                  try
                                  {
                                      Convert.ToDouble(featurePt.DataRow[zField]);
                                  }
                                  catch
                                  {
                                      continue;
                                  }

                                  if (power == 2)
                                  {
                                      top += (1 / (distanceToCell * distanceToCell)) * Convert.ToDouble(featurePt.DataRow[zField]);
                                      bottom += (1 / (distanceToCell* distanceToCell));
                                  }
                                  else
                                  {
                                      top += (1 / Math.Pow(distanceToCell, power)) * Convert.ToDouble(featurePt.DataRow[zField]);
                                      bottom += (1 / Math.Pow(distanceToCell, power));
                                  }
                              }
                        }

                        output.Value[y, x] = top / bottom;
                    }

                    //Checks if we need to update the status bar
                    if (Convert.ToInt32(Convert.ToDouble(x*numRows ) / Convert.ToDouble(numColumns * numRows) * 100) > lastUpdate)
                    {
                        lastUpdate = Convert.ToInt32(Convert.ToDouble(x * numRows) / Convert.ToDouble(numColumns * numRows) * 100);
                        cancelProgressHandler.Progress("", lastUpdate, "Cell: " + (x * numRows) + " of " + (numColumns * numRows));
                        if (cancelProgressHandler.Cancel)
                        return false;
                    }
                }
                System.Diagnostics.Debug.WriteLine(sw.ElapsedMilliseconds);
            }

            output.Save();
            return true;
        }
Example #2
0
        private double KDTreeTestForecastingValue(List <double> QPreviousT, List <double> QT, int KValue)
        {
            MapWindow.Analysis.Topology.KDTree.KDTree KD = new MapWindow.Analysis.Topology.KDTree.KDTree(2);

            double[] Corordinates = new double[2];

            for (int i = 1; i < QT.Count; i++)
            {
                //X Coordinate  for Previous Day records [t-1]
                Corordinates[0] = QPreviousT[i];
                //Y Coordinate for Current Day records [t]
                Corordinates[1] = QT[i];

                object Val = (object)(Corordinates);

                KD.Insert(Corordinates, Val);
            }

            //This is guess X coordinate value,which means the one day before the forecasting day value
            double LastdayValue = QT[QT.Count - 1];

            double PreviousDay = QPreviousT[QPreviousT.Count - 1];

            //This is guess Y coordinate value,which means the forecasting day value
            double GuessValue = LastdayValue + ((LastdayValue - PreviousDay) / 2);

            double[] Finalcheck = new double[2];
            //X Coordinate
            Finalcheck[0] = LastdayValue;

            //Y Coordinate
            Finalcheck[1] = GuessValue;

            object[] val = KD.Nearest(Finalcheck, KValue);


            double XDistance;
            double XSqrDistance;
            double YDistance;
            double YSqrDistance;

            List <double> finalDistnace = new List <double>();
            List <double> finalWeights  = new List <double>();
            double        weight        = 0;
            double        distance      = 0;

            for (int j = 0; j < val.Length; j++)
            {
                double[] val2 = (double[])(val[j]);

                XDistance    = LastdayValue - val2[0];
                XSqrDistance = XDistance * XDistance;
                YDistance    = GuessValue - val2[1];
                finalWeights.Add(val2[1]);
                YSqrDistance = YDistance * YDistance;
                finalDistnace.Add(Math.Sqrt(XSqrDistance + YSqrDistance));
            }



            for (int k = 0; k < finalDistnace.Count; k++)
            {
                if (finalDistnace[k] == 0)
                {
                    weight   += finalWeights[k] / 1.0;
                    distance += 1 / 1.0;
                }
                else
                {
                    weight   += finalWeights[k] / finalDistnace[k];
                    distance += 1 / finalDistnace[k];
                }
            }

            double forecastingValue = weight / distance;

            //  KD.Delete(Corordinates);

            return(forecastingValue);
        }